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.