Wybór pustego pola tekstowego za pomocą jQuery

103

Jak zidentyfikować puste pola tekstowe za pomocą jQuery? Chciałbym to zrobić używając selektorów, jeśli to w ogóle możliwe. Muszę również wybrać identyfikator, ponieważ w rzeczywistym kodzie, w którym chcę tego użyć, nie chcę wybierać wszystkich danych wejściowych.

W poniższych dwóch przykładach kodu, pierwszy z nich dokładnie wyświetla wartość wpisaną przez użytkownika w polu tekstowym „txt2”. Drugi przykład wskazuje, że istnieje puste pole tekstowe, ale jeśli je wypełnisz, nadal uważa je za puste. Dlaczego to?

Czy można to zrobić za pomocą samych selektorów?

Ten kod zgłasza wartość w polu tekstowym „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>

Ten kod zawsze zgłasza pole tekstowe „txt2” jako puste:

<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
źródło
6
Czy ktoś wie, czy „[value =]” ignoruje dane wejściowe użytkownika i sprawdza tylko to, co jest w źródle?
Cros
Czy mam rację, że: pusty filtr jest przeznaczony do tej pracy? $ ('input [type = text]: empty'). doStuff ();
Antony Carthy
1
przeczytaj dokumentację - docs.jquery.com/Selectors/empty . Puste dotyczy elementów, które nie mają dzieci, NIE mają wartości
Russ Cam

Odpowiedzi:

196

Inny sposób

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

lub

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

lub

// 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=""]');

Działające demo

kod z wersji demonstracyjnej

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
źródło
Dla mnie: if ($ ('[id ^ = txt]'). Filter (function () {return $ (this) .val () == "";}). Length> 0) {alert ('WARNING' ); }
Cros
Co odróżnia twój ostatni przykład od mojego drugiego? Muszę wybrać na id, ponieważ w prawdziwym kodzie nie będę patrzeć na wszystkie dane wejściowe. Mój drugi przykład nie działa z danymi wejściowymi użytkownika, ale twój działa.
Cros
1
Działający selektor wydaje się mieć do czynienia z: tekstem w selektorze - jeśli otworzysz działające demo i dodasz / edytujesz adres URL, możesz bawić się używanym selektorem. Jeśli zdejmiesz: text, selektor nie będzie już działał poprawnie, nawet z $ ('input [value = ""]'). Prawdopodobnie błąd w silniku selektora Sizzle, ale nie mam czasu na badanie. Nawiasem mówiąc, sugerowałbym użycie tagu elementu w selektorze, w przeciwnym razie każdy element zostanie sprawdzony, aby zobaczyć, czy istnieje dopasowanie wartości atrybutów.
Russ Cam
3
Niezła odpowiedź! Ale możesz również chcieć upewnić się, że wartość elementu wejściowego jest dosłownie zerowa (spacje!). W takim przypadku należy wyciąć puste przestrzenie. Coś w tym stylu$('input:text').filter(function() { return $(this).val().trim() == ""; });
Vineeth Pradhan
31
Zwróć uwagę, że jeśli element jest obecny, ale nie ma atrybutu value, [value=""]selector nie działa, ponieważ nie znajduje atrybutu value. Jednak technika .filter działa w tym scenariuszu.
AaronLS
26

Możesz to również zrobić, definiując własny selektor:

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

A następnie uzyskaj do nich dostęp w ten sposób:

alert($(':text:textboxEmpty').length); //alerts the number of text boxes in your selection
James Wiseman
źródło
Jestem trochę zaniepokojony występem. Ale prawdopodobnie najłatwiejsza odpowiedź!
aliqandil
19
$(":text[value='']").doStuff();

?

Nawiasem mówiąc, Twój telefon:

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

można znacznie uprościć i przyspieszyć dzięki:

$('#cmdSubmit')...
cletus
źródło
Chyba brakuje zamykającego nawiasu kwadratowego. Typowe źródło jQuery nie działa zgodnie z oczekiwaniami, trudne do wykrycia: - /
OregonGhost
Twój pierwszy przykład jest w zasadzie tym, co robi mój przykład niedziałający. Chcę wiedzieć, czy użytkownik dodał tekst do pola wejściowego, Twój przykład tego nie robi.
Cros
Spieszyłem się, twój przykład wydaje się działać, ale nie wybiera na id, co muszę zrobić.
Cros
Wykonywanie „input [id = ..]” to nie to samo, co „#”. # nie daje tablicy obiektów.
dev4life,
@ dev4life, jeśli używasz wielu elementów na stronie o tym samym identyfikatorze, robisz to źle
Sean Kendle
12

Jak wspomniano w poście o najwyższym rankingu, poniższe elementy działają z silnikiem Sizzle.

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

W komentarzach zauważono, że usunięcie :textczęści selektora powoduje awarię selektora. Wierzę, że to, co się dzieje, polega na tym, że Sizzle faktycznie polega na wbudowanym silniku selektora przeglądarki, gdy to możliwe. Po :textdodaniu do selektora staje się niestandardowym selektorem CSS i dlatego musi być obsługiwany przez samą Sizzle. Oznacza to, że Sizzle sprawdza bieżącą wartość INPUT zamiast atrybutu „value” określonego w źródłowym HTML.

Jest to więc sprytny sposób sprawdzania pustych pól tekstowych, ale myślę, że opiera się on na zachowaniu specyficznym dla silnika Sizzle (czyli używaniu bieżącej wartości INPUT zamiast atrybutu zdefiniowanego w kodzie źródłowym). Chociaż Sizzle może zwrócić elementy pasujące do tego selektora, document.querySelectorAllzwróci tylko elementy, które mają value=""w kodzie HTML. Caveat emptor.

trzecia osoba
źródło
4

Opierając się na odpowiedzi @Jamesa Wisemana, używam tego:

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

Spowoduje to przechwycenie danych wejściowych zawierających tylko białe znaki oprócz tych, które są „naprawdę” puste.

Przykład: http://jsfiddle.net/e9btdbyn/

Gruffy
źródło
3

Polecam:

$('input:text:not([value])')
TM.
źródło
2
To nie zadziała, ponieważ [atrybut] szuka obecności atrybutu, a nie tego, czy ma on wartość, czy nie. <input value="">nadal będą pasować.
Ben Hull,
Było to pomocne dla mnie podczas używania Laravel do generowania pól formularza (np. {{Form::text('first_name', Input::old('first_name'), array('class' => 'form-control', 'required'))}}), Ponieważ Laravel nie dodaje atrybutu „wartość”, jeśli jest on pusty. Więc użyłem: $('input:text:not([value]):visible:enabled:first');aby znaleźć pierwsze widoczne puste, włączone pole wprowadzania tekstu.
Ryan
3

Jest tu wiele odpowiedzi sugerujących coś takiego, [value=""]ale nie sądzę, aby to faktycznie działało. . . a przynajmniej użycie nie jest spójne. Próbuję zrobić coś podobnego, wybierając wszystkie dane wejściowe z identyfikatorami zaczynającymi się od określonego ciągu, który również nie ma wprowadzonej wartości. Próbowałem tego:

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

ale to nie działa. Ani też ich odwrócenie. Zobacz to skrzypce . Jedyne sposoby, jakie znalazłem, aby poprawnie wybrać wszystkie dane wejściowe z identyfikatorami zaczynającymi się od ciągu i bez wprowadzonej wartości, to

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

i

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

ale oczywiście podwójne negatywy sprawiają, że jest to naprawdę zagmatwane. Prawdopodobnie pierwsza odpowiedź Russa Cama (z funkcją filtrującą) jest najbardziej przejrzystą metodą.

tandrewnichols
źródło
1

Spowoduje to wybranie pustych danych wejściowych z identyfikatorem zaczynającym się od „txt”:

$(':text[value=""][id^=txt]')
Cros
źródło
0

Ponieważ tworzenie obiektu JQuery dla każdego porównania nie jest wydajne, wystarczy użyć:

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

Następnie możesz:

$(":input:blank")
Opony
źródło