Просмотр полной версии : Checkbox ajax unchecked не передает значение
katalizator
03.04.2020, 20:32
Доброго дня.
Стоит задача: есть несколько полей - чекбоксов.
При установке галочки, значение value уходит в обработчик, при снятии уходит пустое значение.
Необходимо чтоб при снятии галочки, в обработчик уходил также значение value как и при установке.
Вот код:
<form method="post" action="this.form.submit();" name="form1">
<input type="checkbox" name="category[]" onclick="function1();" value="1">Поле 1
<input type="checkbox" name="category[]" onclick="function1();" value="2">Поле 2
<input type="checkbox" name="category[]" onclick="function1();" value="3">Поле 3
</form>
function function1() {
var data = $("[name='form1']").serialize();
$.ajax({
url: "action.php",
type: "POST",
async: true,
cache: false,
data: data
});
}
Подскажите пожалуйста, как должен выглядеть рабочий код.
JQ не отправляет на сервер не выбранные флажки, да и зачем?
katalizator
03.04.2020, 21:04
JQ не отправляет на сервер не выбранные флажки, да и зачем?
обработчик записывает новое значение в базу... Если галочка стоит - 1, если галочка снята - 0. В value содержится id поля, значение которого необходимо обновить.
Т.е. если галочку я снимаю, мне необходимо чтобы обработчик сохранил новое значение.
Как проверяет сервер? Ведь ему не сложно проверить - если есть в данных параметр значит пишем 1, если нет, то нет. А еще разумнее в базе дать полю значение по умолчанию, тогда в базу нужно записывать только пришедшие поля, конечно, если речь не идет об обновлении. Только именование полей как category[] без явных указаний ключей (без привязки) в данном случае есть плохой подход.
Если же все-таки все охота получить, то не используйте .serialize(), вместо этого получите все элементы формы, добавив их в отправление.
katalizator
04.04.2020, 13:31
если речь не идет об обновлении.
в том-то и дело что обновление. Ладно, спасибо большое за ответ. Придётся переходить на radio.
Придётся переходить на radio
Приехали, называется. :) Флажки и радио, это как небо и земля по предназначению, а значит ваши флажки изначально были не к месту.
katalizator
04.04.2020, 14:11
Приехали, называется. :) Флажки и радио, это как небо и земля по предназначению, а значит ваши флажки изначально были не к месту.
:) предполагается включение/отключение категории (1/0 в базе). С точки зрения интерфейса, хотелось сделать это путём установки снятия галочки, но придется через radio ВКЫЛ/ВЫКЛ
Флажок, это элемент для выбора множества из множества. Аналогом флажкам в базе является поле типа SET. А радио кнопки служат для выбора одного значения из множества. Их аналогам в базе является поле типа ENUM.
Если флажки служат для вкл/выкл и это набор, значит каждый флажок, это одно поле в таблице базы. Как можно гарантированно связать флажки с полями в базе именуя их category[]? Никак, так как не выбранный флажок браузер на сервер не отправляет и если будут выбраны все флажки, то все будет ОК, но стоит один из них сбросить, все пойдет крахом.
В таких случаях нужно явно определять ключ флажкам, например как category[id категории], или value флажков содержит id категории. В этом случае сбоя не произойдет, сервер всегда будет знать флажки каких категорий выбраны и нужно обновить.
У вас же все не по людски. ;)
katalizator
04.04.2020, 14:43
Помогите пожалуйста написать правильно код...
Вот что имею сейчас:
Есть форма:
<form method="post" action="this.form.submit();" name="form1">
<input type="checkbox" name="category[]" onclick="function1();" value="1">Поле 1
<input type="checkbox" name="category[]" onclick="function1();" value="2">Поле 2
<input type="checkbox" name="category[]" onclick="function1();" value="3">Поле 3
...
<input type="checkbox" name="category[]" onclick="function1();" value="n">Поле n
</form>
Есть попытка отправить данные в обработчик:
function function1() {
var data = $("[name='form1']").serialize();
$.ajax({
url: "action.php",
type: "POST",
async: true,
cache: false,
data: data
});
}
В базе у каждого поля есть столбец "enable" принимающее значение 1 или 0 (вкыл или выкл).
Обработчику (action.php) надо при нажатии на галочку (чекбокс или радио), получить id поля для которого меняем состояние, и само состояние (1 или 0) и дальше соответственно обновить инф-ю в базе. Вот как правильно эти данные обработчику передать, не могу разобраться.
Понимаю что делаю явно что-то не по людски)) Но с JS знаком немного больше чем никак...
У вас проблемы не в JS, а в связях параметры->база. Что означают значения полей? Зачем изменение флажка запускает отправление формы на сервер?
Вот ваши проблемы. Если обновление в базе должно производиться индивидуально по изменению каждого флажка, то действовать нужно не так, то что у вас, это ближе к групповому обновлению. Но в любом случае нужна связь, а что к чему у вас я ведь не знаю. Могу сказать только, что поля в качестве значений могут содержать индекс поля таблицы базы, то есть 1, 2, 3 ... это номера полей. На сервере можно это связать с реальными именами полей.
action="this.form.submit();" - эту абракадабру заменить на
action="action.php"
Вместо name="form1" выгоднее id="form1". onclick="function1();" удалить вообще из полей. Для более удобного управления флажками их нужно дополнить метками, например так - <label><input type="checkbox" name="category[]" value="1">Поле 1</label>.
Форма имеет "логическую ошибку", которая заключается в том, что она служит для обновления полей таблицы базы, но при этом не отражает текущее состояние полей этой таблицы. Следовательно результатом обновления может быть совсем не то, что ожидается.
Пусть форма отдана клиенту как положено, с отражением текущего состояния полей и дополнениями указанными выше.
<form method="post" action="action.php" id="form1">
<label><input type="checkbox" name="category[]" value="1" checked="">Поле 1</label>
<label><input type="checkbox" name="category[]" value="2">Поле 2</label>
<label><input type="checkbox" name="category[]" value="3" checked="">Поле 3</label>
<input type="hidden" name="?" value="1" />
</form>
Если каждое изменение флажка, это запрос сервера на обновление, то обработчик должен быть:
$('#form1').on('change', function(e) {
var f = e.delegateTarget;
$.ajax({
url: f.action,
type: f.method,
data: //???
})
});
То есть, по изменению флажка в обработчике не проблема получить адрес отправления, метод, и состояние флажка, которое получать в обработчике как - +e.target.checked. Но вот что за параметр, то есть куму этот флажок будет адресован на сервере, это вопрос. Также вопросом остается определение владельца записи в базе. Если владелец записи (идентификатор) определен в форме скрытым полем, то под каким именем? И если это имя поля, то почему флажки не имеют таковых? Вот с чего у вас начинаются проблемы, форма сама по себе, сервер сам по себе, а JS как грабли, которыми пытаются все это в одну кучу, авось получится. Нет, не получится.
Такие параметры как статусы объекта, режимы отображения и т.п., которые в базе описываются как булевы значения (вкл/выкл) удобнее производить как групповое обновление, что более оперативно, чем индивидуально каждое поле. Пример ниже описан под PDO (это не обязательно), в нем можно оперировать именными метками, что более наглядно. Для примера в таблице имеются три записи (с идентификаторами 1, 2 и 3), а таблица имеет пять полей: поле идентификатора записи и четыре поля значений, соответственно именам: id, a, b, c, d. То есть, индексы полей будут равны id => 0, a => 1, b => 2, c => 3, d => 4. И мы будет оперировать не именами полей, а их индексами.
Сервер формируя форму для клиента получает информацию о таблице: состояния значений ее полей, а также их имена, можно получить и комментарии полей, которые вполне могут служить текстами меток полей формы. На основе этих данных и должна строится форма, обходом данных в цикле. Пусть в итоге она будет иметь следующий код:
<form method="post" action="action.php" id="form1">
<label><input type="checkbox" name="category[1][1]" value="1" checked="">Поле a</label>
<label><input type="checkbox" name="category[1][2]" value="1">Поле b</label>
<label><input type="checkbox" name="category[1][3]" value="1">Поле c</label>
<label><input type="checkbox" name="category[1][4]" value="1" checked="">Поле d</label>
<br />
<label><input type="checkbox" name="category[2][1]" value="1">Поле a</label>
<label><input type="checkbox" name="category[2][2]" value="1">Поле b</label>
<label><input type="checkbox" name="category[2][3]" value="1" checked="">Поле c</label>
<label><input type="checkbox" name="category[2][4]" value="1">Поле d</label>
<br />
<label><input type="checkbox" name="category[3][1]" value="1">Поле a</label>
<label><input type="checkbox" name="category[3][2]" value="1">Поле b</label>
<label><input type="checkbox" name="category[3][3]" value="1" checked="">Поле c</label>
<label><input type="checkbox" name="category[3][4]" value="1">Поле d</label>
<br />
<button>Send</button>
</form>
Здесь поля формы именуются следующим образом category[идентификатор записи, значение поля id таблицы][индекс значащих полей a, b, c и d]. А значения полей определяем равные 1. Выбрав/сбросив флажки у каждой из трех записей отправляем форму, обработчик которой в этом случае будет иметь вид:
$('#form1').submit(function(e) {
e.preventDefault();
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize()
})
});
Сервер получит массив category, первичными ключами которого будут идентификаторы владельцев записей, а вторичными ключами индексы значащих полей, флажки которых выбраны на клиенте. Получив информацию о таблице, сервер будет иметь массив описывающий ее поля, под индексами, с которыми они расположены в базе, и которые будут равны индексам пришедших флажков формы.
$fields = ['id', 'a', 'b', 'c', 'd'];
На основе этого массива подготавливается запрос в базу:
$sth = $db->prepare('UPDATE table_name SET a = :a, b = :b, c = :c, d = :d WHERE id = :id');
Далее в цикле из массива полей таблицы и пришедших полей формы для каждой записи формируется ассоциативный массив данных для обновления каждой записи:
foreach($_POST['category'] as $id=>$values) {
//значение по умолчанию для полей равные 0
$default = array_fill(0, count($fields), 0);
//устанавливаем 1 полей, у которых были выбраны флажки
//значения 0 индексов массива $default равных ключам пришедших флажков
//будут заменены на 1 значений флажков
$data = array_replace($default, $values);
//добавляем значение идентификатора записи
$data[0] = $id;
//формируем ассоциативный массив данных для обновления
$data = array_combine($fields, $data);
//обновляем запись в базе
$sth->execute($data);
}
Стоит заметить, что можно сразу подготовить данные обновления для всех записей и используя ON DUPLICATE KEY UPDATE выполнить всего один запрос в базу для обновления всех записей, вместо множества запросов для каждой записи.
vBulletin® v3.6.7, Copyright ©2000-2025, Jelsoft Enterprises Ltd. Перевод: zCarot