Выбор пустого ввода текста с помощью jQuery

103

Как определить пустые текстовые поля с помощью jQuery? Я бы хотел сделать это с помощью селекторов, если это вообще возможно. Кроме того, я должен выбрать идентификатор, так как в реальном коде, где я хочу его использовать, я не хочу выбирать все текстовые поля.

В следующих двух примерах кода первый точно отображает значение, введенное пользователем в текстовое поле «txt2». Во втором примере показано, что текстовое поле пустое, но если вы его заполните, оно все равно будет считаться пустым. Почему это?

Можно ли это сделать, используя только селекторы?

Этот код сообщает значение в текстовом поле «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>

Этот код всегда сообщает текстовое поле "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() {
                    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
источник
6
Кто-нибудь знает, игнорирует ли '[value =]' ввод пользователя и проверяет только то, что находится в источнике?
Cros
Я прав, что для этой работы создан фильтр: empty? $ ('ввод [тип = текст]: пустой'). doStuff ();
Энтони Карти,
1
прочтите документацию - docs.jquery.com/Selectors/empty . «Пусто» используется для элементов, у которых нет дочерних элементов, а НЕ без значения
Расс Кэм,

Ответы:

196

По-другому

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

или

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

или

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

Рабочая демонстрация

код из демонстрации

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);
  });

});
Расс Кэм
источник
Для меня: if ($ ('[id ^ = txt]'). Filter (function () {return $ (this) .val () == "";}). Length> 0) {alert ('WARNING' ); }
Cros
Что отличает ваш последний пример от моего второго? Мне нужно выбрать id, так как в реальном коде я не буду смотреть на все вводимые данные. Мой второй пример не работает с пользовательским вводом, но ваш - работает.
Cros
1
Рабочий селектор, похоже, связан с: текстом в селекторе - если вы откроете рабочую демонстрацию и добавите / отредактируете URL-адрес, вы можете поиграть с используемым селектором. Если вы удалите: text, селектор больше не будет работать правильно, даже с $ ('input [value = ""]'). Возможно, это ошибка в движке селектора Sizzle, но у меня нет времени разбираться. Кстати, я бы предложил использовать тег элемента в селекторе, иначе каждый элемент будет проверяться, чтобы увидеть, есть ли совпадения для значений атрибутов.
Russ Cam
3
Хороший ответ! Но вы также можете убедиться, что значение входного элемента буквально равно нулю (пробелы!). В этом случае не забудьте вырезать пустые места. Что-то вроде этого$('input:text').filter(function() { return $(this).val().trim() == ""; });
Vineeth Pradhan
31
Обратите внимание: если элемент присутствует, но не имеет атрибута значения, то [value=""]селектор не работает, поскольку он не находит атрибут значения. Однако метод .filter действительно работает в этом сценарии.
AaronLS 01
26

Вы также можете сделать это, определив свой собственный селектор:

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

А затем получить к ним доступ следующим образом:

alert($(':text:textboxEmpty').length); //alerts the number of text boxes in your selection
Джеймс Уайзман
источник
Меня немного беспокоит производительность. Но наверное самый простой ответ!
aliqandil 03
19
$(":text[value='']").doStuff();

?

Кстати, ваш звонок:

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

можно значительно упростить и ускорить с помощью:

$('#cmdSubmit')...
Cletus
источник
Думаю, здесь не хватает закрывающей квадратной скобки. Распространенный источник jQuery, который не работает
должным образом
Ваш первый пример - это в основном то, что делает мой неработающий пример. Я хочу знать, добавил ли пользователь текст в поле ввода, ваш пример этого не делает.
Cros
Я поторопился, ваш пример, похоже, работает, но он не выбирает идентификатор, что я должен сделать.
Cros
Выполнение «input [id = ..]» не то же самое, что «#». # не дает вам массив объектов.
dev4life
@ dev4life, если вы используете несколько элементов на странице с одним и тем же идентификатором, вы делаете это неправильно
Шон Кендл,
12

Как упоминалось в посте с самым высоким рейтингом, с движком Sizzle работает следующее.

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

В комментариях было отмечено, что удаление :textчасти селектора приводит к сбою селектора. Я считаю, что происходит то, что Sizzle по возможности полагается на встроенный в браузер механизм выбора. Когда :textон добавляется к селектору, он становится нестандартным селектором CSS и, следовательно, должен обрабатываться самим Sizzle. Это означает, что Sizzle проверяет текущее значение INPUT вместо атрибута «value», указанного в исходном HTML.

Так что это умный способ проверить пустые текстовые поля, но я думаю, что он полагается на поведение, специфичное для движка Sizzle (то есть использование текущего значения INPUT вместо атрибута, определенного в исходном коде). Хотя Sizzle может возвращать элементы, соответствующие этому селектору, document.querySelectorAllвернет только те элементы, которые есть value=""в HTML. Пусть покупатель будет бдителен.

садовод
источник
4

Основываясь на ответе @James Wiseman, я использую это:

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

Это перехватит входы, которые содержат только пробелы в дополнение к тем, которые «действительно» пусты.

Пример: http://jsfiddle.net/e9btdbyn/

Грубый
источник
3

Я бы рекомендовал:

$('input:text:not([value])')
TM.
источник
2
Это не сработает, потому что [attribute] проверяет наличие атрибута, а не то, имеет он значение или нет. <input value="">все равно будет совпадать.
Бен Халл
Это было полезно для меня при использовании Laravel для генерации полей формы (например {{Form::text('first_name', Input::old('first_name'), array('class' => 'form-control', 'required'))}}), потому что Laravel не добавляет атрибут «значение», если он пуст. Поэтому я затем использовал: $('input:text:not([value]):visible:enabled:first');чтобы найти первое видимое пустое активированное поле ввода текста.
Райан
3

Здесь много ответов, предлагающих что-то вроде, [value=""]но я не думаю, что это действительно работает. . . или, по крайней мере, использование непоследовательно. Я пытаюсь сделать что-то подобное, выбирая все входы с идентификаторами, начинающимися с определенной строки, которая также не имеет введенного значения. Я пробовал это:

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

но это не работает. И не обратить их вспять. Посмотри на эту скрипку . Единственными способами, которые я нашел для правильного выбора всех входов с идентификаторами, начинающимися со строки и без введенного значения, были

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

и

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

но очевидно, что двойное отрицание действительно сбивает с толку. Наверное, первый ответ Расс Кэма (с функцией фильтрации) - самый понятный метод.

тандревичолс
источник
1

Это выберет пустые текстовые поля с идентификатором, начинающимся с «txt»:

$(':text[value=""][id^=txt]')
Cros
источник
0

Поскольку создание объекта JQuery для каждого сравнения неэффективно, просто используйте:

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

Тогда вы сможете:

$(":input:blank")
Шины
источник