jQuery serialize registriert keine Kontrollkästchen

76

Ich verwende jQuery.serialize, um alle Datenfelder in einem Formular abzurufen.

Mein Problem ist, dass keine Kontrollkästchen abgerufen werden, die nicht aktiviert sind.

Es beinhaltet Folgendes:

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

aber nicht das

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

Wie kann ich "Werte" von Kontrollkästchen erhalten, die nicht aktiviert sind?

Steven
quelle
2
Was wir in ASP Net tun, ist eine versteckte Eingabe: <input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" checked="checked" Value="On" /> <input type="hidden" name="event_allDay" Value="Off" /> Wenn dies nicht aktiviert ist, wird der Wert der versteckten Eingabe angenommen
Carlos Martinez T

Antworten:

72

jQuery serializeahmt genau nach, wie ein Standardformular vom Browser serialisiert wird, bevor es an die Abfragezeichenfolge oder den POST-Text in der Anforderung angehängt wird. Nicht aktivierte Kontrollkästchen werden vom Browser nicht eingeschlossen, was wirklich sinnvoll ist, da sie einen booleschen Status haben - sie werden entweder vom Benutzer ausgewählt (enthalten) oder nicht vom Benutzer ausgewählt (nicht enthalten).

Wenn Sie es für die Serialisierung benötigen, sollten Sie sich fragen: "Warum? Warum nicht einfach prüfen, ob es in den Daten vorhanden ist?".

Beachten Sie, dass Sie die Möglichkeit einer ordnungsgemäßen Verschlechterung Ihres Formulars ausschließen, wenn sich die Art und Weise, wie JavaScript Formulardaten serialisiert, anders verhält als der Browser. Wenn Sie dies immer noch unbedingt tun müssen, verwenden Sie einfach eine <select>Box mit Ja / Nein als Optionen. Zumindest dann sind Benutzer mit deaktiviertem JS nicht von Ihrer Site entfremdet und Sie verstoßen nicht gegen das in der HTML-Spezifikation definierte Verhalten.

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

Ich habe dies in der Vergangenheit auf einigen Websites gesehen und mir immer gedacht: "Warum verwenden sie nicht einfach ein Kontrollkästchen ? "

Andy E.
quelle
20
Dies würde das Speichern von Informationen in der Datenbank erheblich vereinfachen. Denn dann würde die Anzahl der Felder aus Serialize der Anzahl der Felder in der Tabelle entsprechen. Jetzt muss ich kontrollieren, welche fehlen.
Steven
19
Es gibt einen guten Grund, ungeprüfte Kontrollkästchen und nicht gesetzte Radiobuttons zu wollen. Die Werte für diese Felder sind möglicherweise bereits auf dem Server vorhanden und Sie möchten lediglich aktualisieren. Wenn Sie diese Werte nicht in Ihrer Übermittlungszeichenfolge haben, wird davon ausgegangen, dass Sie den Datensatz jedes Mal vollständig überschreiben.
Mydoghaswürmer
4
@mydog: warum sollte das jemals der Fall sein? Es scheint eine schlechte Wahl für das Design zu sein, wenn Sie mich fragen. Diese Felder würden sich niemals in der Abfragezeichenfolge befinden, wenn der Browser die Formulardaten übermitteln würde. Warum sollten Sie sie also so gestalten, dass sie für JavaScript anders sind? Sie würden zunächst einmal jede Möglichkeit einer würdevollen Verschlechterung vollständig ausschließen.
Andy E
1
@AndyE Manchmal haben Sie einen Server, auf dem alle Optionen explizit angegeben werden müssen. Warum sollte dies ein seltener Fall sein?
Glenn
1
HTML sollte sich als Ansicht verhalten und keine Entscheidungen darüber treffen, welche Daten an einen "Controller" gesendet werden. Wie die Daten interpretiert werden, sollte in der Verantwortung des "Controllers" liegen - der Sache, die den Formularpost bearbeitet.
Muglio
79

Um auf der genialen Antwort von Azatoth aufzubauen, habe ich sie für mein Szenario leicht erweitert:

    /* 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()
    );
Mydoghaswürmer
quelle
7
hat bei mir nicht funktioniert, also habe ich eine kleine Änderung vorgenommen: return {"name": this.name, "value": 'off'}
xeo
1
ich liebe dich. Ich habe mich bemüht, eine Lösung für mein Problem zu finden, und dies kam über Google. Vielen Dank
Justin
Vielen Dank! Genau das brauchte ich!
jared_flack
funktioniert nur, wenn Sie serializeArray()nicht nur verwendenserialize()
Chaudhry Waqas
1
Dies funktionierte für mich besser als die akzeptierte Antwort, aber "this.checked" gab mir den Status des Kontrollkästchens, anstatt "this.value" zu verwenden. Ich habe auch den jquery-Selektor auf ": checkbox" geändert, da ich alle Kontrollkästchen benötigte.
Paul
27

Sie tun dies nicht, da Serialize als Abfragezeichenfolge verwendet werden soll. In diesem Zusammenhang bedeutet "Deaktiviert", dass es sich überhaupt nicht im Abfragering befindet.

Wenn Sie wirklich die Werte von nicht aktivierten Kontrollkästchen erhalten möchten, verwenden Sie: (natürlich nicht getestet)

var arr_unchecked_values = $('input[type=checkbox]:not(:checked)').map(function(){return this.value}).get();
Azatoth
quelle
Die Antwort unten erweitert dies sehr gut.
Steampowered
17

Wenn Sie unserer Abfragezeichenfolge unserialisierte Kontrollkästchen hinzufügen möchten, fügen Sie Ihrer jquery submit-Funktion Folgendes hinzu:

var moreinfo = '';

$('input[type=checkbox]').each(function() {     
    if (!this.checked) {
        moreinfo += '&'+this.name+'=0';
    }
});
Mazatec
quelle
Dadurch wird die Möglichkeit einer geringfügigen Verschlechterung Ihres Formulars ausgeschlossen. Die übermittelten Daten sind für Benutzer mit deaktiviertem JS unterschiedlich.
Andy E
Ich muss sagen, wenn Sie die Funktion .serialize () verwenden, ist dies die beste Lösung. Var data = $ ("# userinput_form"). Serialize (); $ ('# userinput_form input [type = checkbox]: not (: checked)'). each (function () {data + = '&' + this.name + '= 0';});
Windmaomao
5

jQuery serialize ruft das Wertattribut von Eingaben ab.

Wie können Sie nun das Kontrollkästchen und das Optionsfeld zum Laufen bringen? Wenn Sie das Klickereignis des Kontrollkästchens oder des Optionsfelds 0 oder 1 festlegen, werden die Änderungen angezeigt.

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

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

und auch wann immer Sie das Kontrollkästchen mit aktiviertem Status aktivieren möchten, z. B. PHP

<input type='checkbox' value="<?php echo $product['check']; ?>" checked="<?php echo $product['check']; ?>" />
Wut
quelle
2
Dieser Code funktioniert. Grundsätzlich sieht das Kontrollkästchen-Steuerelement wie eine normale Eingabe (Typ textoder a select) für die serialize()Funktion aus, indem dem Kontrollkästchen eine valueEigenschaft zugewiesen wird , die mit dem aktivierten Status synchron bleibt. Und es ist eleganter als die ausgewählte Antwort.
Annabel
Wenn Sie für .Net MVC die Werte True und False verwenden, können Sie mithilfe der Magie der MVC-Modellzuordnung Ihre booleschen Modelleigenschaften festlegen. Fügen Sie diese Attribute zu Ihrem <Eingang> hinzu, um eine korrekte Darstellung der Ansicht zu erhalten: value = "@ (Model.Item2.IsCurrent?" True ":" False ")" @ (Model.Item2.IsCurrent? "Checked = 'checked'" : "")
DavidCC
4

Hier ist eine weitere Lösung, die die Methode "serializeArray" erweitert (wobei das ursprüngliche Verhalten beibehalten wird).

//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;
    }
});

Dadurch werden tatsächlich boolesche Ergebnisse "true" oder "false" angehängt. Wenn Sie dies jedoch bevorzugen, können Sie "1" bzw. "0" verwenden, indem Sie den Wert in ändern value: $item.is(":checked") ? 1 : 0.

Verwendung

Rufen Sie wie gewohnt die Methode in Ihrem Formular auf: $form.serialize()oder $form.serializeArray(). Was passiert , ist , dass serializeMarken verwenden serializeArraysowieso, so dass Sie die richtigen Ergebnisse erhalten (obwohl anderes Format) mit je nachdem , welche Methode Sie anrufen.

bigp
quelle
FEHLER: Mein schlechtes, wenn das Kontrollkästchen "wahr" ist, wird immer noch ein Parameter mit dem üblichen "Ein" -Wert angehängt.
Ich werde das
Wenn das Kontrollkästchen aktiviert ist, erhalten Sie im Ergebnis 2 Werte mit demselben Namen ... einen mit 'on' und einen, den Sie am Ende mit '1' hinzufügen ...
WonderLand
Ich habe das Problem behoben :)
WonderLand
4

Sie können handleInputs()add in Ihrer Submit-Funktion vor Ajax aufrufen

function handleInputs(){
    $('input[type=checkbox]').each(function() {     
        if (!this.checked) {
            $(this).attr("value","0");
        }else{
            $(this).attr("value","1");
        }
    });
}

Es funktioniert perfekt

Ferhat KOÇER
quelle
3

Eine Technik, die ich in meinen eigenen Systemen verwendet habe und von der ich glaube, dass sie von Struts angewendet wird, besteht darin, ...

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

... direkt neben dem Kontrollkästchen als Teil meiner Formularerstellungslogik.

Auf diese Weise kann ich rekonstruieren, welche Kontrollkästchen im Formular bereitgestellt, aber nicht ausgewählt wurden. Mit ein wenig zusätzlicher Logik, um den Unterschied zu machen, was bereitgestellt und was aktiviert wurde, haben Sie diejenigen, die deaktiviert wurden. Die Übermittlung ist auch inhaltlich gleich, unabhängig davon, ob Sie eine Übermittlung im HTML- oder AJAX-Stil verwenden.

Abhängig von der Technologie, die Sie serverseitig verwenden, möchten Sie möglicherweise diese Syntax verwenden ...

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

... um es einfach zu machen, diese Werte als Liste zu erfassen.

Cefn Hoile
quelle
3

Für ASP.NET MVC speichern wir erfolgreich ein Formular mit Kontrollkästchen über einen AJAX- POST mit den folgenden Methoden. Dies ist eine Kombination mehrerer Methoden, auf die in diesem Beitrag verwiesen wird , einschließlich des Vorschlags von @Jecoms :

var form = $('#myForm');
// Serialize the form into a JavaScript object using the jQuery.serializeObject plugin
// https://plugins.jquery.com/serializeObject/
var data = form.serializeObject();
// Change the submitted value of checkboxes to the value of the checked property
$('#myForm input[type=checkbox]').each( function () { data[this.name] = this.checked; } );
// For a MVC controller, convert the JS object back into a query string using jQuery.param function
data = $.param(data);
// Perform AJAX POST with the form data
$.ajax({
    async: true,
    url: 'mvcActionMethodURL',
    type: 'POST',
    data: data,
    success: function (data, textStatus, xhr) {

    },
    error: function (xhr, status, error) {

    }
});
iCode
quelle
2

Ein Grund für die Verwendung einer nicht standardmäßigen Checkbox-Serialisierung, die in der Frage oder in den aktuellen Antworten nicht behandelt wird, besteht darin, nur Felder zu deserialisieren (zu ändern), die explizit in den serialisierten Daten angegeben wurden - z. B. wenn Sie jquery serialization und deserialization to verwenden / aus einem Cookie zum Speichern und Laden von Einstellungen.

Thomas Danemar hat eine Änderung an der Standardmethode implementiert serialize(), um optional eine checkboxesAsBoolsOption zu wählen : http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/ - Dies ähnelt der oben aufgeführten Implementierung von @mydoghasworms, aber auch in die Standard-Serialisierung integriert.

Ich habe es nach Github kopiert, falls jemand zu irgendeinem Zeitpunkt Verbesserungen vornehmen muss: https://gist.github.com/1572512

Darüber hinaus deserialisiert das Plugin "jquery.deserialize" jetzt die Kontrollkästchenwerte, mit denen serialisiert wurde checkboxesAsBools, korrekt und ignoriert Kontrollkästchen, die in den serialisierten Daten nicht erwähnt werden: https://github.com/itsadok/jquery.deserialize

Tao
quelle
2
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();
Nutzer
quelle
3
Könnten Sie Ihre Antwort überhaupt erklären?
Ben
Diese Antwort ändert das Kontrollkästchen in ein verstecktes Feld, sodass es serialisiert werden kann. Diese Antwort macht das Formular jedoch zu einer einmaligen Verwendung, da Änderungen am DOM vorgenommen werden.
Grant
2

Der Trick besteht darin, den Formularbeitrag abzufangen und die Kontrollkästchen in ausgeblendete Eingabefelder zu ändern.

Beispiel: Einfach einreichen

$('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);
        }
    });
});

Beispiel: AJAX

Sie müssen durch ein paar weitere Rahmen springen, wenn Sie das Formular über Ajax veröffentlichen, um die Benutzeroberfläche nicht zu aktualisieren.

$('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());
Muglio
quelle
2

Dadurch werden die Kontrollkästchenwerte Ihres Formulars anhand ihres aktivierten Status auf Boolesche Werte gesetzt.

var form = $('#myForm');
var data = form.serializeObject();

$('#myForm input[type=checkbox]').each(function() { data[this.name] = this.checked; });

Das von uns verwendete Framework erstellt zwei Eingaben mit demselben Namen, was zu unerwartetem Verhalten bei der Serialisierung des Formulars führt. Ich würde jeden Kontrollkästchenwert als Array mit zwei Elementen und Zeichenfolgenwerten analysieren lassen. Abhängig davon, wie Sie die Datenserver-Seite zuordnen, erhalten Sie möglicherweise unbeabsichtigte Ergebnisse.

Jecoms
quelle
1
serializeObject () scheint ein jQuery-Plugin zu sein: plugins.jquery.com/serializeObject
iCode
Es gibt ein sehr kleines serializeObject(): benalman.com/projects/jquery-misc-plugins/#serializeobject
Bernhard Döbler
1

Die Verwendung von ausgewählten Feldern, wie von Andy vorgeschlagen, ist nicht unbedingt die beste Option für die Benutzererfahrung, da zwei Mausklicks anstelle von einem erforderlich sind.

Darüber hinaus belegt eine "Auswahl" viel mehr Platz in der Benutzeroberfläche als ein Kontrollkästchen.

Ashs Antwort ist eine einfache Lösung, funktioniert aber bei Array-Feldern nicht .

In meinem Kontext habe ich ein Formular mit variabler Länge, das Zeilen enthält, in denen eine Mischung aus Text- und Kontrollkästchenfeldern angezeigt wird:

<input type="checkbox" value="1" name="thisIsAChkArray[]"/> 
<input type="text" value="" name="thisIsATxtArray[]"/>

Für die Dekodierung der gesendeten Daten ist die Reihenfolge der Array-Elemente wichtig. Das Anhängen der nicht aktivierten Elemente an eine reguläre Jquery-Serialisierung behält nicht die Reihenfolge der Zeilenelemente bei.

Hier ist eine vorgeschlagene Lösung, die auf Ashs Antwort basiert:

(function($) {
  $.fn.serializeWithChkBox = function() {
    // perform a serialize form the non-checkbox fields
    var values = $(this).find('select')
                        .add(  $(this).find('input[type!=checkbox]') )
                        .serialize();
    // add values for checked and unchecked checkboxes fields
    $(this).find('input[type=checkbox]').each(function() {
      var chkVal = $(this).is(':checked') ? $(this).val() : "0";
      values += "&" + $(this).attr('name') + "=" + chkVal;
    });
    return values;
  }
})(jQuery);
Eosphäre
quelle
1

Ich hatte ein ähnliches Problem und im Folgenden konnte ich alle Formulareingabewerte und aktivierten / deaktivierten Kontrollkästchen erfassen.

var serialized = this.$('#myform input').map(function() {
return { name: this.name, id: this.id, value: this.checked ? "checked" : "false" };
});
wooz16
quelle
Das "this. $" ist spezifisch für ein Zendesk-App-Framework, mit dem ich für diese Lösung gearbeitet habe.
wooz16
1

In diesem Beispiel wird davon ausgegangen, dass Sie ein Formular über serializeund nicht zurück senden möchten serializeArrayund dass ein deaktiviertes Kontrollkästchen Folgendes bedeutet false:

var form = $(formSelector);
var postData = form.serialize();

var checkBoxData = form.find('input[type=checkbox]:not(:checked)').map(function () {
    return encodeURIComponent(this.name) + '=' + false;
}).get().join('&');

if (checkBoxData) {
    postData += "&" + checkBoxData;
}

$.post(action, postData);
Dominik Holland
quelle
Ich mag den not(:checked)Selektor
Bernhard Döbler
1

Für diejenigen, die die serialize()Funktion verwenden:

(function ($) {
    var serialize = $.fn.serialize;

    $.fn.serialize = function () {
        let values = serialize.call(this);
        let checkboxes = [];

        checkboxes = checkboxes.concat(
            $('input[type=checkbox]:not(:checked)', this).map(
            function () {
                return this.name + '=false';
            }).get()
        );

        if(checkboxes.length > 0)
            values = checkboxes.join('&') + '&' + values;

        return values;
    };
})(jQuery);
Isaac Adams
quelle
0

manchmal bedeutet nicht markiert, dass andere Werte, zum Beispiel aktiviert, ja, nicht markiert, nein oder 0,1 usw. bedeuten können. Dies hängt von der Bedeutung ab, die Sie angeben möchten.

"Es würde das Speichern von Informationen in der Datenbank erheblich vereinfachen. Da dann die Anzahl der Felder von Serialize der Anzahl der Felder in der Tabelle entspricht. Jetzt muss ich steuern, welche fehlen", haben Sie Recht, das ist auch mein Problem. .. so scheint es, dass ich nach diesem nicht existierenden Wert suchen muss ....

aber vielleicht könnte dies eine Lösung sein? http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/

Geomorillo
quelle
1
Wenn die Nichtexistenz ein Problem verursacht, sollten Sie eine <select>Option mit Ja / Nein verwenden, anstatt etwas zu erstellen, das der Definition der zu übermittelnden HTML-Spezifikation durch die HTML-Spezifikation widerspricht.
Andy E
0

Fügen Sie einfach eine versteckte Eingabe hinzu

<input type="hidden" name="your_specific_name">

braucht keinen Wert, ich habe getestet, dass dies für mich funktioniert

jk jk
quelle
1
Bitte elborate. Versuchen Sie, Codebeispiele hinzuzufügen und möglicherweise einen Link zur Dokumentation zu erstellen.
Yotam Omer
0

Sie können den Eingabewert mit jquery serialize abrufen

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="event_allDay" name="event_allDay" checked="checked" onchange="isChecked(this)" value="" />
<script>
    function isChecked(element) {
        $(element).val($(element).is(':checked').toString());
    }
    isChecked('#event_allDay');
</script>

Mustafa Cevat Boz
quelle
0

Um die obigen Antworten zu erweitern, musste ich in meinem Fall ein Ja / Nein für eine einzelne ID senden, die für meinen Backend-Fang serialisiert wurde.

Ich habe die Kontrollkästchenelemente so eingestellt, dass sie die ID einer bestimmten Datenbankspalte enthalten, auch bekannt als (standardmäßig aktiviert) :

(Laravel-Klinge)

<div class="checkbox">
    <label>
        <input type="checkbox" value="{{ $heading->id }}" checked> {{ $heading->name }}
    </label>
</div>

Als ich meine Einreichung machte, griff ich nach den Daten mit:

(jQuery)

let form = $('#formID input[type="checkbox"]').map(function() {
                return { id: this.value, value: this.checked ? 1 : 0 };
           }).get();

var data = JSON.stringify(form);
$.post( "/your/endpoint", data );
Gewähren
quelle
0

Ich habe diesen Weg benutzt und Werte "0" oder wenn "1" markiert. Wenn der Kontrollkästchen-Eingabename in serialisiert nicht vorhanden form_dataist, bedeutet dies, dass er nicht aktiviert ist. Fügen Sie den Wert als Null ( form_data += '&' + name + '=0') serialize()hinzu. Wenn die aktivierte Funktion aktiviert ist, wird er automatisch hinzugefügt.

   /*get all other form inputs*/ 
   var form_data = form.serialize();

    /*get checkboxes*/
    $.each($("#form_id input[type='checkbox']"), function(){
        var name = $(this).attr('name');
        if(form_data.indexOf(name)===-1)form_data += '&' + name + '=0';
    });
WebMan
quelle
-1

Versuche dies:

$ (': input [type = "checkbox"]: checked'). map (function () {return this.value}). get ();

Sam Deering
quelle
-1

Ich poste die Lösung, die für mich funktioniert hat!

var form = $('#checkboxList input[type="checkbox"]').map(function() {
               return { name: this.name, value: this.checked ? this.value : "false" };
            }).get();

var data = JSON.stringify(form);

data value is : "[{"name":"cb1","value":"false"},{"name":"cb2","value":"true"},{"name":"cb3","value":"false"},{"name":"cb4","value":"true"}]"
Alim TUNC
quelle