Wie verwende ich jQuerys form.serialize, schließe aber leere Felder aus?

107

Ich habe ein Suchformular mit einer Reihe von Texteingaben und Dropdown-Listen, die über ein GET gesendet werden. Ich möchte eine sauberere Such-URL haben, indem ich die leeren Felder aus dem Querystring entferne, wenn eine Suche durchgeführt wird.

var form = $("form");  
var serializedFormStr = form.serialize();  
// I'd like to remove inputs where value is '' or '.' here
window.location.href = '/search?' + serializedFormStr

Irgendeine Idee, wie ich das mit jQuery machen kann?

Tom Viner
quelle

Antworten:

167

Ich habe mir die jQuery-Dokumente angesehen und denke, wir können dies in einer Zeile mit Selektoren tun :

$("#myForm :input[value!='']").serialize() // does the job!

Natürlich erhält #myForm das Element mit der ID "myForm", aber was mir zunächst weniger klar war, war, dass das Leerzeichen zwischen #myForm und: input benötigt wird, da es sich um den Nachkommenoperator handelt .

: Eingabe entspricht allen Eingabe-, Textbereichs-, Auswahl- und Schaltflächenelementen.

[value! = ''] ist ein Attribut ungleich Filter. Das Seltsame (und Hilfreiche) ist, dass alle: Eingabeelementtypen Wertattribute haben, sogar Auswahl- und Kontrollkästchen usw.

Schließlich, um auch Eingaben zu entfernen, bei denen der Wert '.' War. (wie in der Frage erwähnt):

$("#myForm :input[value!=''][value!='.']").serialize()

In diesem Fall impliziert das Nebeneinander, dh das Platzieren von zwei Attributselektoren nebeneinander , ein UND. Die Verwendung eines Kommas impliziert ein ODER. Entschuldigung, wenn das für CSS-Leute offensichtlich ist!

Tom Viner
quelle
3
@Mvision, das liegt daran, dass diese Antwort eine kleine, aber signifikante Lücke enthält. Ordnet für normale / reine CSS-Selektoren in jQuery 1.8 und früheren [value]Versionen jedem Element das value vorhandene Attribut zu , einschließlich solcher mit leeren Werten (oder keinen Werten). Dies ist auf einen Fehler in früheren jQuery-Versionen zurückzuführen, der zu einer Inkonsistenz zwischen bestimmten Variationen von input[value]und führte :input[value]. Nehmen Sie zum Beispiel <input value="foo"><input value=""><input value><input>; Der Fehler ist in dieser Geige dargestellt .
Noyo
4
Für mich hat das funktioniert: $form.find(":input[value]")- leere Felder wurden nicht ausgewählt. Dies hat nicht funktioniert: $form.find(":input[value!='']")- Alle Felder wurden ausgewählt. Hoffe das hilft jemandem. (jQuery 2.0.0)
Ryan Wheale
1
$form.find(":input[value]")arbeitete auch für mich (jQuery 1.11.0)
GSTAR
Funktionierte nur, wenn das valueAttribut bereits vorhanden war. Es erkannte es nicht anders.
Starcorn
1
In einigen Fällen, in denen dies valueprogrammgesteuert festgelegt ist, funktioniert dies nicht ( valueexistiert nicht als HTML-Attribut, sondern als Datenattribut für die Eingabe). Versuchen Sie in diesen Fällen Folgendes : $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). EDIT: Ich habe gerade Richs Antwort auf den gleichen Effekt gesehen.
Fateh Khalsa
54

Ich konnte Toms Lösung nicht zum Laufen bringen (?), Aber ich konnte dies .filter()mit einer kurzen Funktion tun , um leere Felder zu identifizieren. Ich verwende jQuery 2.1.1.

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();
Reich
quelle
2
Die genehmigte Antwort konnte nicht funktionieren, aber das hat großartig funktioniert! Vielen Dank!
Bfritz
Beantwortung meiner eigenen Frage: "Der :inputSelektor wählt grundsätzlich alle Formularsteuerelemente aus. Wählt alle Eingabe-, Textbereichs-, Auswahl- und Schaltflächenelemente aus." Quelle
Dinei
Ja, Tom ist kaputt . Ihre ist sauberer als mein Versuch in dieser Geige auch. Up'd
Hashbrown
11

Das funktioniert bei mir:

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();
RMazitov
quelle
Nun, Callback lässt Pass-Werte zurückgeben, gibt true zurück, !!tippt alles in bool um, Sie können es in der Konsole versuchen. !!('test'), !!(5),!!(0)
Aiphee
2
Und anstelle des inputSelektors sollte es :inputauch
Selects
Ich schlage diese Änderung vor:data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize();
Mahoor13
9

Sie könnten es mit einem regulären Ausdruck tun ...

var orig = $('#myForm').serialize();
var withoutEmpties = orig.replace(/[^&]+=\.?(?:&|$)/g, '')

Testfälle:

orig = "a=&b=.&c=&d=.&e=";
new => ""

orig = "a=&b=bbb&c=.&d=ddd&e=";
new => "b=bbb&d=ddd&"  // dunno if that trailing & is a problem or not
nickf
quelle
.replace (/[^&‹+=\.?(& | $) / g, '') deckt beide Fälle ab. Aber ich würde .replace (/ & $ /, '') hinzufügen, um das nachfolgende &
Tom Viner
15
Es gibt kein Problem, dass Regex nicht schlimmer machen kann.
Michael Cook
3

Ich habe die obige Lösung verwendet, aber für mich haben diese nicht funktioniert. Also habe ich folgenden Code verwendet

$('#searchform').submit(function(){

            var serializedData = $(this).serializeArray();
            var query_str = '';

            $.each(serializedData, function(i,data){
                if($.trim(data['value'])){
                    query_str += (query_str == '') ? '?' + data['name'] + '=' + data['value'] : '&' + data['name'] + '=' + data['value'];
                }
            });
            console.log(query_str);
            return false;
        });

Kann für jemanden nützlich sein

Rajan Rawal
quelle
1

Ich würde mir den Quellcode für jQuery ansehen. In der neuesten Version Zeile 3287.

Ich könnte die Funktionen "serialize2" und "serializeArray2" hinzufügen. Nennen Sie sie natürlich etwas Gemeines.

Oder der bessere Weg wäre, etwas zu schreiben, um die nicht verwendeten Variablen aus serializedFormStr herauszuholen. Ein Regex, der nach = & in der Mitte der Zeichenfolge sucht oder mit = endet. Gibt es Regex-Assistenten?

UPDATE: Ich mag die Antwort von rogeriopvl besser (+1) ... zumal ich momentan keine guten Regex-Tools finde.

BuddyJoe
quelle
1

Eine Alternative zu Richs Lösung :

$('#form').submit(function (e) {
  e.preventDefault();

  var query = $(this).serializeArray().filter(function (i) {
    return i.value;
  });

   window.location.href = $(this).attr('action') + (query ? '?' + $.param(query) : '');
});

Erklärungen:

  • .submit()hängt sich an das submitEreignis des Formulars an
  • e.preventDefault() verhindert, dass das Formular gesendet wird
  • .serializeArray() gibt uns eine Array-Darstellung der Abfragezeichenfolge, die gesendet werden sollte.
  • .filter() Entfernt falsche (einschließlich leerer) Werte in diesem Array.
  • $.param(query) erstellt eine serialisierte und URL-kompatible Darstellung unseres aktualisierten Arrays
  • Festlegen eines Werts zum window.location.hrefSenden der Anforderung
Kathandrax
quelle
0

Gehen Sie in Coffeescript folgendermaßen vor:

serialized_form = $(_.filter($(context).find("form.params input"), (x) -> $(x).val() != '')).serialize()
John Goodsen
quelle
-1

Vielleicht möchten Sie sich die .each () -Jquery-Funktion ansehen, mit der Sie jedes Element eines Selektors durchlaufen können. Auf diese Weise können Sie jedes Eingabefeld überprüfen und feststellen, ob es leer ist oder nicht, und es dann aus dem Formular entfernen using element.remove (). Danach können Sie das Formular serialisieren.

rogeriopvl
quelle
1
Das einzige Problem dabei ist, dass der Benutzer sieht, dass die leeren Steuerelemente kurz vor dem Senden der Seite verschwinden. Es wäre besser, den Namen auf "" zu setzen, damit die Serialisierung ihn ignoriert.
Tom Viner