Comment utiliser le form.serialize de jQuery mais exclure les champs vides

107

J'ai un formulaire de recherche avec un certain nombre d'entrées de texte et de listes déroulantes qui se soumettent via un GET. Je voudrais avoir une URL de recherche plus propre en supprimant les champs vides de la chaîne de requête lorsqu'une recherche est effectuée.

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

Une idée de comment je peux faire cela en utilisant jQuery?

Tom Viner
la source

Réponses:

167

J'ai regardé les documents jQuery et je pense que nous pouvons le faire en une seule ligne à l'aide de sélecteurs :

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

Évidemment, #myForm obtient l'élément avec l'identifiant "myForm" mais ce qui m'était moins évident au début était que le caractère d'espace est nécessaire entre #myForm et: input car c'est l' opérateur descendant .

: l'entrée correspond à tous les éléments input, textarea, select et button.

[value! = ''] est un attribut différent de filtre. La chose étrange (et utile) est que tout: les types d'élément d' entrée ont des attributs de valeur même des sélections et des cases à cocher, etc.

Enfin pour supprimer également les entrées où la valeur était «.» (comme mentionné dans la question):

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

Dans ce cas, la juxtaposition, c'est-à-dire placer deux sélecteurs d'attributs l'un à côté de l'autre , implique un ET. L'utilisation d'une virgule implique un OU. Désolé si c'est évident pour les gens de CSS!

Tom Viner
la source
3
@Mvision, c'est parce qu'il y a une petite mais importante omission dans cette réponse. Pour les sélecteurs CSS normaux / purs dans jQuery 1.8 et versions antérieures, [value]correspond à tout élément avec l'attribut value présent , y compris ceux avec des valeurs vides (ou aucune) valeur. Cela est dû à un bogue dans les versions antérieures de jQuery qui a créé une incohérence entre certaines variantes de input[value]et :input[value]. Prenez, par exemple <input value="foo"><input value=""><input value><input>,; le bug est illustré dans ce violon .
Noyo
4
Pour moi, cela a fonctionné: $form.find(":input[value]")- les champs vides n'ont pas été sélectionnés. Cela n'a pas fonctionné: $form.find(":input[value!='']")- tous les champs ont été sélectionnés. J'espère que cela aide quelqu'un. (jQuery 2.0.0)
Ryan Wheale
1
$form.find(":input[value]")a également travaillé pour moi (jQuery 1.11.0)
GSTAR
Ne fonctionnait que si l' valueattribut était déjà là. Il ne l'a pas reconnu autrement.
starcorn
1
Dans certains cas où valueest défini par programme, cela ne fonctionnera pas ( valuen'existera pas en tant qu'attribut HTML, mais en tant qu'attribut de données sur l'entrée). Dans ces cas, essayez ceci: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). EDIT: Je viens de voir la réponse de Rich dans le même sens.
Fateh Khalsa
54

Je n'ai pas pu faire fonctionner la solution de Tom (?), Mais j'ai pu le faire en utilisant .filter()une fonction courte pour identifier les champs vides. J'utilise jQuery 2.1.1.

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();
Riches
la source
2
Impossible d'obtenir la réponse approuvée, mais cela a très bien fonctionné! Merci!
bfritz
Répondant à ma propre question: "Le :inputsélecteur sélectionne essentiellement tous les contrôles de formulaire. Sélectionne tous les éléments d'entrée, de zone de texte, de sélection et de bouton." source
Dinei
Ouais, celui de Tom est cassé . Le vôtre est plus propre que ma tentative dans ce violon aussi. Up'd
Hashbrown
11

Cela fonctionne pour moi:

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();
RMazitov
la source
Eh bien, le rappel laisse passer les valeurs retournant true, !!retape tout ce qui est booléen, vous pouvez essayer dans la console. !!('test'), !!(5),!!(0)
Aiphee
2
Et au lieu du inputsélecteur, il devrait y avoir :inputpour inclure des sélections, etc.
Aiphee
Je suggère ce changement:data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize();
Mahoor13
9

Vous pouvez le faire avec une regex ...

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

Cas de 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
nickf
la source
.replace (/[^& </font>+=\.?(& | $) / g, '') couvre les deux cas. Mais j'ajouterais .replace (/ & $ /, '') pour supprimer le &
Tom Viner
15
Il n'y a aucun problème que l'expression régulière ne peut aggraver.
Michael Cook
3

J'ai utilisé la solution ci-dessus mais pour moi, cela n'a pas fonctionné. J'ai donc utilisé le code suivant

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

Peut être utile pour quelqu'un

Rajan Rawal
la source
1

Je regarderais le code source de jQuery. Dans la dernière ligne de version 3287.

Je pourrais ajouter des fonctions "serialize2" et "serializeArray2". bien sûr, nommez-les quelque chose de méchant.

Ou le meilleur moyen serait d'écrire quelque chose pour extraire les variables inutilisées de serializedFormStr. Une expression régulière qui recherche = & au milieu de la chaîne ou se terminant par = Des assistants d'expression régulière?

MISE À JOUR: J'aime mieux la réponse de rogeriopvl (+1) ... d'autant plus que je ne trouve pas de bons outils de regex pour le moment.

BuddyJoe
la source
1

Une alternative à la solution de 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) : '');
});

Explications:

  • .submit()s'accroche à l' submitévénement du formulaire
  • e.preventDefault() empêche le formulaire de se soumettre
  • .serializeArray() nous donne une représentation sous forme de tableau de la chaîne de requête qui allait être envoyée.
  • .filter() supprime les valeurs fausses (y compris vides) dans ce tableau.
  • $.param(query) crée une représentation sérialisée et conforme à l'URL de notre tableau mis à jour
  • définition d'une valeur pour window.location.hrefenvoyer la demande
Kathandrax
la source
0

Dans coffeescript, procédez comme suit:

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

Vous voudrez peut-être regarder la fonction jquery .each (), qui vous permet de parcourir chaque élément d'un sélecteur, de cette façon, vous pouvez vérifier chaque champ de saisie et voir s'il est vide ou non, puis le supprimer du formulaire en utilisant element.remove (). Après cela, vous pouvez sérialiser le formulaire.

rogeriopvl
la source
1
Le seul problème avec cela est que l'utilisateur verra les contrôles vides disparaître juste avant la soumission de la page. Il vaudrait mieux définir le nom sur "" afin que serialize l'ignore.
Tom Viner