Как использовать jQuery form.serialize, но исключить пустые поля

У меня есть форма поиска с несколькими текстовыми вводами и раскрывающимися списками, которые отправляются через GET. Я хотел бы иметь более чистый URL-адрес поиска, удалив пустые поля из строки запроса при выполнении поиска.

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

Любая идея, как я могу сделать это с помощью jQuery?


person Tom Viner    schedule 03.03.2009    source источник


Ответы (9)


Я просмотрел документы jQuery и думаю, что мы можем сделать это в одной строке, используя селекторы:

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

Очевидно, что #myForm получает элемент с идентификатором "myForm", но поначалу мне было менее очевидно, что символ пробела необходим между #myForm и :input, поскольку это потомок.

:input соответствует всем элементам input, textarea, select и button.

[value!=''] — это фильтр, не равный атрибуту. Странная (и полезная) вещь заключается в том, что все типы элементов :input имеют атрибуты значений, даже выборки, флажки и т. д.

Наконец, чтобы также удалить входы, где значение было '.' (как указано в вопросе):

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

В этом случае сопоставление, то есть размещение двух селекторов атрибутов рядом друг с другом, подразумевает И. Запятая подразумевает ИЛИ. Извините, если это очевидно для людей, занимающихся CSS!

person Tom Viner    schedule 04.03.2009
comment
@Mvision, это потому, что в этом ответе есть небольшое, но существенное упущение. Для обычных/чистых селекторов CSS в jQuery 1.8 и более ранних версиях [value] соответствует любому элементу с атрибутом value присутствует, включая элементы с пустыми значениями (или без значений). Это связано с ошибкой в ​​более ранних версиях jQuery, которая создавала несоответствие между некоторыми вариантами input[value] и :input[value]. Возьмем, к примеру, <input value="foo"><input value=""><input value><input>; ошибка проиллюстрирована в этой скрипте. - person Noyo; 15.07.2013
comment
У меня это сработало: $form.find(":input[value]") - пустые поля не выбраны. Это не сработало: $form.find(":input[value!='']") - выбраны все поля. Надеюсь, это поможет кому-то. (JQuery 2.0.0) - person Ryan Wheale; 07.06.2014
comment
$form.find(":input[value]") у меня тоже работало (jQuery 1.11.0) - person MAXIM; 19.08.2014
comment
Работает только в том случае, если атрибут value уже существует. Иного не признавал. - person starcorn; 31.08.2015
comment
В некоторых случаях, когда value устанавливается программно, это не сработает (value не будет существовать как атрибут HTML, но будет как атрибут данных на входе). В таких случаях попробуйте следующее: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). РЕДАКТИРОВАТЬ: Только что увидел ответ Рича на тот же эффект. - person Fateh Khalsa; 13.04.2017
comment
Удивительно... так просто. Для меня это сработало очень хорошо для всех скрытых входов $("#my-form :input:visible").serialize() - person Pedro Simões; 02.08.2018
comment
Стоит отметить, что это работает только для элементов управления формы, которые фактически находятся в теге формы - похоже, не работает (да я и не ожидал) с элементами управления формы, которые используют атрибут form="". - person Tieson T.; 05.11.2019

Мне не удалось заставить решение Тома работать (?), но я смог сделать это, используя .filter() с короткой функцией для определения пустых полей. Я использую jQuery 2.1.1.

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();
person Rich    schedule 13.02.2015
comment
Не удалось заставить утвержденный ответ работать, но это сработало отлично! Спасибо! - person bfritz; 28.02.2017
comment
Отвечая на мой собственный вопрос: селектор :input в основном выбирает все элементы управления формой. Выбирает все элементы input, textarea, select и button. источник - person Dinei; 26.04.2017
comment
Да, у Тома не работает. Ваша попытка чище, чем моя попытка в этой скрипке. вверх - person Hashbrown; 20.07.2018

Вы можете сделать это с помощью регулярного выражения...

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

Тестовые случаи:

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
person nickf    schedule 04.03.2009
comment
.replace(/[^&]+=\.?(&|$)/g, '') охватывает оба случая. Но я бы добавил .replace(/&$/, '') чтобы удалить замыкающие & - person Tom Viner; 04.03.2009
comment
Нет проблем, которые регулярное выражение не может ухудшить. - person Michael Cook; 21.11.2013

Это работает для меня:

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();
person RMazitov    schedule 12.05.2015
comment
Ну, обратный вызов позволяет передавать значения, возвращающие true, !! перепечатывает что-либо в bool, вы можете попробовать в консоли. !!('test'), !!(5), !!(0) - person Aiphee; 09.03.2016
comment
А вместо селектора input должно быть :input для включения селекторов и т.д. - person Aiphee; 09.03.2016
comment
Я предлагаю это изменение: data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize(); - person Mahoor13; 16.03.2020

Я использовал вышеуказанное решение, но для меня это не сработало. Итак, я использовал следующий код

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

Может кому пригодится

person Rajan Rawal    schedule 15.02.2014

Я бы посмотрел на исходный код для jQuery. В последней версии строка 3287.

Я мог бы добавить функции «serialize2» и «serializeArray2». конечно, назовите их что-нибудь осмысленное.

Или лучше написать что-нибудь, чтобы вытащить неиспользуемые переменные из serializedFormStr. Некоторое регулярное выражение, которое ищет =& в середине строки или заканчивается на = Есть ли поблизости мастера регулярных выражений?

ОБНОВЛЕНИЕ: мне больше нравится ответ rogeriopvl (+1)... тем более что сейчас я не могу найти хороших инструментов для регулярных выражений.

person BuddyJoe    schedule 04.03.2009


В кофескрипте сделайте так:

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

Возможно, вы захотите взглянуть на функцию jquery .each(), которая позволяет вам перебирать каждый элемент селектора, поэтому таким образом вы можете проверить каждое поле ввода и посмотреть, пусто оно или нет, а затем удалить его из формы используя element.remove(). После этого вы можете сериализовать форму.

person rogeriopvl    schedule 04.03.2009
comment
Единственная проблема заключается в том, что пользователь увидит, что пустые элементы управления исчезают непосредственно перед отправкой страницы. Было бы лучше установить имя, чтобы сериализация его игнорировала. - person Tom Viner; 04.03.2009