Sélection d'une entrée de texte vide à l'aide de jQuery

103

Comment identifier les zones de texte vides à l'aide de jQuery? Je voudrais le faire en utilisant des sélecteurs si c'est possible. De plus, je dois sélectionner sur id car dans le code réel où je veux utiliser cela, je ne veux pas sélectionner toutes les entrées de texte.

Dans mes deux exemples de code suivants, le premier affiche avec précision la valeur saisie dans la zone de texte "txt2" par l'utilisateur. Le deuxième exemple indique qu'il y a une zone de texte vide, mais si vous la remplissez, elle la considère toujours comme vide. Pourquoi est-ce?

Cela peut-il être fait en utilisant uniquement des sélecteurs?

Ce code signale la valeur dans la zone de texte "txt2":

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(function() {
                $('#cmdSubmit').click(function() {
                    alert($('[id=txt2]').val());
                });             
            });
        </script>
    </head>
    <body>
        <form>
            <input type="text" name="txt1" id="txt1" value="123" /><br />
            <input type="text" name="txt2" id="txt2" value="" /><br />
            <input type="text" name="txt3" id="txt3" value="abc" /><br />
            <input type="submit" name="cmdSubmit" id='cmdSubmit' value="Send" /><br />
        </form>
    </body>
</html>

Ce code signale toujours que la zone de texte "txt2" est vide:

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(function() {
                $('#cmdSubmit').click(function() {
                    if($('[id^=txt][value=""]').length > 0) {
                        if (!confirm("Are you sure you want to submit empty fields?")) {
                            if (event.preventDefault) {
                                event.preventDefault();
                            } else {
                                event.returnValue = false;
                            }
                        }
                    }
                });             
            });
        </script>
    </head>
    <body>
        <form>
            <input type="text" name="txt1" id="txt1" value="123" /><br />
            <input type="text" name="txt2" id="txt2" value="" /><br />
            <input type="text" name="txt3" id="txt3" value="abc" /><br />
            <input type="submit" name="cmdSubmit" id='cmdSubmit' value="Send" /><br />
        </form>
    </body>
</html>
Cros
la source
6
Est-ce que quelqu'un sait si «[value =]» ignore l'entrée de l'utilisateur et ne vérifie que ce qui se trouve dans la source?
Cros
Ai-je raison de dire que le filtre: vide est fait pour ce travail? $ ('input [type = text]: vide'). doStuff ();
Antony Carthy
1
lisez la documentation - docs.jquery.com/Selectors/empty . Vide est pour les éléments qui n'ont pas d'enfants, PAS aucune valeur
Russ Cam

Réponses:

196

Autrement

$('input:text').filter(function() { return $(this).val() == ""; });

ou

$('input:text').filter(function() { return this.value == ""; });

ou

// WARNING: if input element does not have the "value" attribute or this attribute was removed from DOM then such selector WILL NOT WORK! 
// For example input with type="file" and file does not selected.
// It's prefer to use "filter()" method.
// Thanks to @AaronLS
$('input:text[value=""]');

Démo de travail

code de la démo

jQuery

 $(function() {

  $('#button').click(function() {

    var emptyTextBoxes = $('input:text').filter(function() { return this.value == ""; });
    var string = "The blank textbox ids are - \n";

    emptyTextBoxes.each(function() {
      string += "\n" + this.id;
    });
    alert(string);
  });

});
Russ Cam
la source
Pour moi: if ($ ('[id ^ = txt]'). Filter (function () {return $ (this) .val () == "";}). Length> 0) {alert ('WARNING' ); }
Cros
Qu'est-ce qui sépare votre dernier exemple du deuxième? Je dois sélectionner sur id, car dans le vrai code, je ne regarderai pas toutes les entrées de texte. Mon deuxième exemple ne fonctionne pas avec l'entrée de l'utilisateur, mais le vôtre le fait.
Cros
1
Le sélecteur de travail semble être à voir avec: du texte dans le sélecteur - si vous ouvrez la démo de travail et ajoutez / modifiez l'URL, vous pouvez jouer avec le sélecteur utilisé. Si vous supprimez le: text, le sélecteur ne fonctionne plus correctement, même avec $ ('input [value = ""]'). Peut-être un bug dans le moteur de sélection Sizzle, mais je n'ai pas le temps d'enquêter. En passant, je suggérerais d'utiliser une balise d'élément dans le sélecteur, sinon chaque élément sera vérifié pour voir s'il y a une correspondance pour les valeurs d'attribut.
Russ Cam
3
Bonne réponse! Mais vous pouvez également vous assurer que la valeur de l'élément d'entrée est littéralement nulle (espaces vides!). Assurez-vous de supprimer les espaces vides dans ce cas. Quelque chose comme ça$('input:text').filter(function() { return $(this).val().trim() == ""; });
Vineeth Pradhan
31
Notez que si l'élément est présent mais n'a pas d'attribut de valeur, le [value=""]sélecteur ne fonctionne pas car il ne trouve pas d'attribut de valeur. Toutefois, la technique .filter fonctionne dans ce scénario.
AaronLS
26

Vous pouvez également le faire en définissant votre propre sélecteur:

$.extend($.expr[':'],{
    textboxEmpty: function(el){
        return $(el).val() === "";
    }
});

Et puis accédez-y comme ceci:

alert($(':text:textboxEmpty').length); //alerts the number of text boxes in your selection
James Wiseman
la source
Je suis un peu préoccupé par la performance. Mais probablement la réponse la plus simple!
aliqandil
19
$(":text[value='']").doStuff();

?

Au fait, votre appel de:

$('input[id=cmdSubmit]')...

peut être grandement simplifiée et accélérée avec:

$('#cmdSubmit')...
cletus
la source
Je suppose qu'il manque un crochet de fermeture. Une source commune de jQuery ne fonctionne pas comme prévu, difficile à repérer: - /
OregonGhost
Votre premier exemple est essentiellement ce que fait mon exemple qui ne fonctionne pas. Je veux savoir si l'utilisateur a ajouté du texte dans le champ de saisie, votre exemple ne le fait pas.
Cros
J'étais précipité, votre exemple semble fonctionner, mais il ne sélectionne pas sur id, ce que je dois faire.
Cros
Faire "input [id = ..]" n'est pas la même chose que "#". # ne vous donne pas un tableau d'objets.
dev4life
@ dev4life si vous utilisez plusieurs éléments sur une page avec le même identifiant, vous le faites mal
Sean Kendle
12

Comme mentionné dans l'article le mieux classé, ce qui suit fonctionne avec le moteur Sizzle.

$('input:text[value=""]');

Dans les commentaires, il a été noté que la suppression de la :textpartie du sélecteur entraîne l'échec du sélecteur. Je pense que ce qui se passe, c'est que Sizzle s'appuie en fait sur le moteur de sélection intégré du navigateur lorsque cela est possible. Lorsqu'il :textest ajouté au sélecteur, il devient un sélecteur CSS non standard et doit donc être géré par Sizzle lui-même. Cela signifie que Sizzle vérifie la valeur actuelle de INPUT, au lieu de l'attribut "value" spécifié dans le code HTML source.

C'est donc un moyen astucieux de vérifier les champs de texte vides, mais je pense que cela repose sur un comportement propre au moteur Sizzle (celui d'utiliser la valeur actuelle de INPUT au lieu de l'attribut défini dans le code source). Bien que Sizzle puisse renvoyer des éléments qui correspondent à ce sélecteur, document.querySelectorAllne renverra que les éléments qui ont value=""dans le HTML. Caveat emptor.

tiers
la source
4

En me basant sur la réponse de @James Wiseman, j'utilise ceci:

$.extend($.expr[':'],{
    blank: function(el){
        return $(el).val().match(/^\s*$/);
    }
});

Cela capturera les entrées qui ne contiennent que des espaces en plus de celles qui sont «vraiment» vides.

Exemple: http://jsfiddle.net/e9btdbyn/

Gruffy
la source
3

Je recommande:

$('input:text:not([value])')
TM.
la source
2
Cela ne fonctionnera pas, car [attribut] recherche la présence d'un attribut - pas s'il a une valeur ou non. <input value="">correspondra toujours.
Ben Hull
Cela m'a été utile lors de l'utilisation de Laravel pour générer des champs de formulaire (par exemple {{Form::text('first_name', Input::old('first_name'), array('class' => 'form-control', 'required'))}}) parce que Laravel n'ajoute pas d'attribut «valeur» s'il est vide. J'ai donc utilisé: $('input:text:not([value]):visible:enabled:first');pour trouver le premier champ de saisie de texte activé vide visible.
Ryan
3

Il y a beaucoup de réponses ici suggérant quelque chose comme [value=""]mais je ne pense pas que cela fonctionne réellement. . . ou du moins, l'utilisation n'est pas cohérente. J'essaie de faire quelque chose de similaire, en sélectionnant toutes les entrées avec des identifiants commençant par une certaine chaîne qui n'ont pas non plus de valeur entrée. J'ai essayé ceci:

$("input[id^='something'][value='']")

mais ça ne marche pas. Les inverser non plus. Voyez ce violon . Les seuls moyens que j'ai trouvés pour sélectionner correctement toutes les entrées avec des identifiants commençant par une chaîne et sans valeur saisie étaient

$("input[id^='something']").not("[value!='']")

et

$("input[id^='something']:not([value!=''])")

mais évidemment, les doubles négatifs rendent cela vraiment déroutant. La première réponse de Russ Cam (avec une fonction de filtrage) est probablement la méthode la plus claire.

tandrewnichols
la source
1

Cela sélectionnera des entrées de texte vides avec un identifiant commençant par "txt":

$(':text[value=""][id^=txt]')
Cros
la source
0

Étant donné que la création d'un objet JQuery pour chaque comparaison n'est pas efficace, utilisez simplement:

$.expr[":"].blank = function(element) {
    return element.value == "";
};

Ensuite, vous pouvez faire:

$(":input:blank")
Pneus
la source