jQuery serialize не регистрирует флажки - PullRequest
70 голосов
/ 12 июня 2010

Я использую jQuery.serialize для извлечения всех полей данных в форме.

Моя проблема заключается в том, что он не возвращает флажки, которые не отмечены.

Он включает в себя следующее:

<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" checked="checked" />

но не это

<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" />

Как я могу получить "значения" флажков, которые не отмечены?

Ответы [ 24 ]

71 голосов
/ 18 августа 2011

Чтобы развить гениальный ответ Азатота, я немного расширил его для моего сценария:

    /* Get input values from form */
    values = jQuery("#myform").serializeArray();

    /* Because serializeArray() ignores unset checkboxes and radio buttons: */
    values = values.concat(
            jQuery('#myform input[type=checkbox]:not(:checked)').map(
                    function() {
                        return {"name": this.name, "value": false}
                    }).get()
    );
65 голосов
/ 12 июня 2010

jQuery serialize близко имитирует, как стандартная форма будет сериализована браузером перед добавлением в строку запроса или тело POST в запросе. Не отмеченные флажки не включены браузером, что действительно имеет смысл, поскольку они имеют логическое состояние - они либо выбраны пользователем (включены), либо не выбраны пользователем (не включены).

Если вам нужно, чтобы он был в сериализованном виде, вы должны спросить себя «почему? Почему бы просто не проверить его наличие в данных?».

Имейте в виду, что если способ, которым JavaScript сериализует данные формы, ведет себя не так, как в браузере, то вы исключаете любую возможность постепенного ухудшения формы. Если вам все еще необходимо это сделать, просто используйте поле <select> с опциями Да / Нет в качестве параметров. По крайней мере, пользователи с отключенным JS не будут отчуждены от вашего сайта, и вы не будете против определенного поведения в спецификации HTML.

<select id="event_allDay" name="event_allDay">
   <option value="0" selected>No</option>
   <option value="1">Yes</option>
</select>

Я видел это на некоторых сайтах в прошлом и всегда думал про себя: "почему они просто не используют флажок" ?

25 голосов
/ 12 июня 2010

Нет, так как serialize предназначен для использования в качестве строки запроса, и в этом контексте отсутствие отметки означает, что его вообще нет в строке запроса.

Если вы действительно хотите получить значениясняты флажки, используйте: (непроверенный вне курса)

var arr_unchecked_values = $('input[type=checkbox]:not(:checked)').map(function(){return this.value}).get();
17 голосов
/ 12 июня 2010

, если вы хотите добавить несериализованные флажки в строку запроса, добавьте следующее в функцию отправки jquery:

var moreinfo = '';

$('input[type=checkbox]').each(function() {     
    if (!this.checked) {
        moreinfo += '&'+this.name+'=0';
    }
});
4 голосов
/ 02 декабря 2015

Вот еще одно решение, расширяющее метод serializeArray (при сохранении исходного поведения).

//Store the reference to the original method:

var _serializeArray = $ ji.fn.serializeArray;

//Now extend it with newer "unchecked checkbox" functionality:
$ji.fn.extend({
    serializeArray: function () {
        //Important: Get the results as you normally would...
        var results = _serializeArray.call(this);

        //Now, find all the checkboxes and append their "checked" state to the results.
        this.find('input[type=checkbox]').each(function (id, item) {
            var $item = $ji(item);
            var item_value = $item.is(":checked") ? 1 : 0;
            var item_name = $item.attr('name');
            var result_index = null;
            results.each(function (data, index) {
                if (data.name == item_name) {
                    result_index = index;
                }
            });

            if (result_index != null) {
                // FOUND replace previous value
                results[result_index].value = item_value;
            }
            else {
                // NO value has been found add new one
                results.push({name: item_name, value: item_value});
            }
        });
        return results;
    }
});

Thisна самом деле добавит «истинные» или «ложные» логические результаты, но если вы предпочитаете, вы можете использовать «1» и «0» соответственно, изменив значение на value: $item.is(":checked") ? 1 : 0.

Использование

Как обычно, вызовите метод в вашей форме: $form.serialize() или $form.serializeArray().Что происходит, так это то, что serialize в любом случае использует serializeArray, так что вы получите правильные результаты (хотя и в другом формате) с любым вызванным вами методом.

3 голосов
/ 18 декабря 2013

jQuery serialize получает атрибут значения входных данных.

Теперь, как заставить работать флажок и переключатель? Если вы установите событие щелчка для флажка или переключателя 0 или 1, вы сможете увидеть изменения.

$( "#myform input[type='checkbox']" ).on( "click", function(){
     if ($(this).prop('checked')){
          $(this).attr('value', 1);
     } else {
          $(this).attr('value', 0);
     }
 }); 

 values = $("#myform").serializeArray();

а также когда вы захотите установить флажок с проверенным статусом, например, PHP

<input type='checkbox' value="<?php echo $product['check']; ?>" checked="<?php echo $product['check']; ?>" />
3 голосов
/ 21 декабря 2011

Техника, которую я использовал в своих собственных системах и которую, я считаю, использует Struts, должна включать ...

<input type="hidden" name="_fieldname" value="fieldvalue"/> 

... непосредственно рядом с флажком как часть моей логики создания формы.

Это позволяет мне восстановить, какие флажки были предоставлены в форме, но не выбраны, с небольшим количеством дополнительной логики для выполнения сравнения того, что было обслужено и что было проверено, у вас есть те, которые не были проверены. Содержание также одинаково по содержанию, независимо от того, используете ли вы представление в стиле HTML или AJAX.

В зависимости от технологии, которую вы используете на стороне сервера, вы можете использовать этот синтаксис ...

<input type="hidden" name="_fieldname[]" value="fieldvalue"/>

... чтобы было проще получить эти значения в виде списка.

2 голосов
/ 07 января 2012

Одной из причин использования нестандартной сериализации флажков, которая не рассматривается в вопросе или текущих ответах, является только десериализация (изменение) полей, которые были явно указаны в сериализованных данных - например,когда вы используете сериализацию jquery и десериализацию в / из файла cookie для сохранения и загрузки предпочтений.

Томас Данемар реализовал модификацию стандартного метода serialize() для необязательного выбора опции checkboxesAsBools: http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/ - это похоже на реализацию, указанную выше @mydoghasworms, но также интегрировано в стандартную сериализацию.

Я скопировал ее на Github на тот случай, если у кого-то есть улучшения, которые нужно сделать в любой момент: https://gist.github.com/1572512

Кроме того, плагин "jquery.deserialize" теперь правильно десериализует значения флажков, сериализованных с checkboxesAsBools, и игнорирует флажки, которые не упомянуты в сериализованных данных: https://github.com/itsadok/jquery.deserialize

2 голосов
/ 23 июля 2013
var checkboxes = $('#myform').find('input[type="checkbox"]');
$.each( checkboxes, function( key, value ) {
    if (value.checked === false) {
        value.value = 0;
    } else {
        value.value = 1;
    }
    $(value).attr('type', 'hidden');
});
$('#myform').serialize();
2 голосов
/ 19 мая 2015

Хитрость заключается в том, чтобы перехватить сообщение формы и установить флажки на скрытые поля ввода.

Пример: обычная отправка

$('form').on("submit", function (e) {
    //find the checkboxes
    var $checkboxes = $(this).find('input[type=checkbox]');

    //loop through the checkboxes and change to hidden fields
    $checkboxes.each(function() {
        if ($(this)[0].checked) {
            $(this).attr('type', 'hidden');
            $(this).val(1);
        } else {
            $(this).attr('type', 'hidden');
            $(this).val(0);
        }
    });
});

Пример: AJAX

Вам нужно перепрыгнуть через несколько обручей, если вы публикуете форму через ajax, чтобы не обновлять пользовательский интерфейс.

$('form').on("submit", function (e) {
    e.preventDefault();

    //clone the form, we don't want this to impact the ui
    var $form = $('form').clone();

    //find the checkboxes
    var $checkboxes = $form.find('input[type=checkbox]');

    //loop through the checkboxes and change to hidden fields
    $checkboxes.each(function() {
        if ($(this)[0].checked) {
            $(this).attr('type', 'hidden');
            $(this).val(1);
        } else {
            $(this).attr('type', 'hidden');
            $(this).val(0);
        }
    });

    $.post("/your/path", $form.serialize());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...