Come utilizzo form.serialize di jQuery ma escludo i campi vuoti


107

Ho un modulo di ricerca con una serie di input di testo e menu a discesa che invia tramite un GET. Mi piacerebbe avere un URL di ricerca più pulito rimuovendo i campi vuoti dalla stringa di query quando viene eseguita una ricerca.

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

Qualche idea su come posso farlo usando jQuery?

Risposte:


167

Ho esaminato i documenti di jQuery e penso che possiamo farlo in una riga usando i selettori :

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

Ovviamente #myForm ottiene l'elemento con id "myForm", ma quello che all'inizio mi era meno ovvio era che il carattere spazio è necessario tra #myForm e: input poiché è l' operatore discendente .

: input corrisponde a tutti gli elementi input, textarea, select e button.

[valore! = ''] è un attributo diverso dal filtro. La cosa strana (e utile) è che tutti: i tipi di elementi di input hanno attributi di valore anche selezioni e caselle di controllo ecc.

Infine per rimuovere anche gli input in cui il valore era "." (come menzionato nella domanda):

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

In questo caso la giustapposizione, cioè il posizionamento di due selettori di attributi uno accanto all'altro , implica un AND. L'uso di una virgola implica un OR. Scusa se questo è ovvio per le persone CSS!


3
@ Mvision, questo perché c'è una piccola ma significativa omissione in questa risposta. Per i selettori CSS normali / puri in jQuery 1.8 e precedenti, [value]corrisponde a qualsiasi elemento con l'attributo value presente , inclusi quelli con valori vuoti (o nessun valore). Ciò è dovuto a un bug nelle versioni precedenti di jQuery che creava un'incongruenza tra alcune varianti di input[value]e :input[value]. Prendi, ad esempio <input value="foo"><input value=""><input value><input>,; il bug è illustrato in questo violino .
Noyo

4
Per me, questo ha funzionato: $form.find(":input[value]")- i campi vuoti non sono stati selezionati. Questo non ha funzionato: $form.find(":input[value!='']")- sono stati selezionati tutti i campi. Spero che aiuti qualcuno. (jQuery 2.0.0)
Ryan Wheale

1
$form.find(":input[value]")ha funzionato anche per me (jQuery 1.11.0)
GSTAR

Funzionava solo se l' valueattributo era già presente. Altrimenti non l'ha riconosciuto.
starcorn

1
In alcuni casi in cui valueè impostato valuea livello di codice , questo non funzionerà ( non esiste come attributo HTML, ma come attributo dati sull'input). In questi casi, provate questo: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). EDIT: Ho appena visto la risposta di Rich con lo stesso effetto.
Fateh Khalsa

54

Non sono riuscito a far funzionare la soluzione di Tom (?), Ma sono stato in grado di farlo utilizzando .filter()una breve funzione per identificare i campi vuoti. Sto usando jQuery 2.1.1.

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();

2
Non è stato possibile far funzionare la risposta approvata, ma ha funzionato benissimo! Grazie!
bfritz

Rispondendo alla mia domanda: "Il :inputselettore seleziona fondamentalmente tutti i controlli del modulo. Seleziona tutti gli elementi di input, textarea, select e button." fonte
Dinei

Sì, quello di Tom è rotto . Anche il tuo è più pulito del mio tentativo con quel violino. Up'd
Hashbrown

11

Questo funziona per me:

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();

Bene, il callback consente di passare valori che restituiscono true, !!ridigita qualsiasi cosa in bool, puoi provare in console. !!('test'), !!(5),!!(0)
Aiphee

2
E invece del inputselettore, dovrebbe esserci :inputper includere selezioni, ecc.
Aiphee

Suggerisco questa modifica:data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize();
Mahoor13

9

Potresti farlo con un'espressione regolare ...

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

Casi test:

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

.replace (/[^&”+=\.?(& | $) / g, '') copre entrambi i casi. Ma aggiungerei .replace (/ & $ /, '') per rimuovere la &
Tom Viner

15
Non c'è problema che regex non possa peggiorare.
Michael Cook

3

Ho usato la soluzione sopra ma per me quelli non hanno funzionato. Quindi ho usato il seguente codice

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

Può essere utile per qualcuno


1

Guarderei il codice sorgente per jQuery. Nell'ultima versione della linea 3287.

Potrei aggiungere le funzioni "serialize2" e "serializeArray2". ovviamente chiamali qualcosa di meschino.

O il modo migliore sarebbe scrivere qualcosa per estrarre le variabili inutilizzate da serializedFormStr. Qualche regex che cerca = & a metà stringa o che termina con = Eventuali procedure guidate regex in giro?

AGGIORNAMENTO: Mi piace di più la risposta di rogeriopvl (+1) ... soprattutto perché al momento non riesco a trovare nessun buon strumento per le espressioni regolari.


1

Un'alternativa alla soluzione di Rich :

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

spiegazioni:

  • .submit()si aggancia submitall'evento del form
  • e.preventDefault() impedisce l'invio del modulo
  • .serializeArray() ci fornisce una rappresentazione in matrice della stringa di query che stava per essere inviata.
  • .filter() rimuove i valori falsi (inclusi quelli vuoti) in quell'array.
  • $.param(query) crea una rappresentazione serializzata e conforme all'URL del nostro array aggiornato
  • l'impostazione di un valore per window.location.hrefinvia la richiesta

0

In coffeescript, fai questo:

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

-1

Potresti voler guardare la funzione jquery .each (), che ti permette di iterare attraverso ogni elemento di un selettore, quindi in questo modo puoi andare a controllare ogni campo di input e vedere se è vuoto o meno e quindi rimuoverlo dal modulo utilizzando element.remove (). Dopodiché puoi serializzare il modulo.


1
L'unico problema è che l'utente vedrà il vuoto dai controlli scomparire appena prima che la pagina venga inviata. Sarebbe meglio impostare il nome su "" così serializzare lo ignora.
Tom Viner
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.