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


107

У меня есть форма поиска с несколькими текстовыми полями и раскрывающимися списками, которые отправляются через 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?

Ответы:


167

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

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

Очевидно #myForm получает элемент с идентификатором «Myform» , но то , что было менее очевидным для меня в первый том , что символ пробела необходимо между #myForm и: вход , как это потомок оператора.

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

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

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

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

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


3
@Mvision, это потому, что в этом ответе есть небольшое, но существенное упущение. Для обычных / чистых селекторов CSS в jQuery 1.8 и ранее [value]соответствует любому элементу с value присутствующим атрибутом , включая элементы с пустыми значениями (или без значений). Это связано с ошибкой в ​​более ранних версиях jQuery, которая создавала несоответствие между некоторыми вариантами input[value]и :input[value]. Возьмем, например <input value="foo"><input value=""><input value><input>,; ошибка проиллюстрирована на этой скрипке .
Noyo

4
У меня это сработало: $form.find(":input[value]")- пустые поля не выбирались. Не сработало: $form.find(":input[value!='']")- выбраны все поля. Надеюсь, это кому-то поможет. (jQuery 2.0.0)
Райан Уил

1
$form.find(":input[value]")также работал у меня (jQuery 1.11.0)
GSTAR

Работал только в том случае, если valueатрибут уже был там. Иначе он этого не узнал.
Starcorn

1
В некоторых случаях, когда valueэто установлено программно, это не сработает ( valueне будет существовать как атрибут HTML, но будет как атрибут данных на входе). В тех случаях, попробуйте следующее: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). РЕДАКТИРОВАТЬ: только что видел ответ Рича на тот же эффект.
Fateh Khalsa

54

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

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();

2
Не удалось получить утвержденный ответ, но это отлично сработало! Спасибо!
bfritz

Отвечая на свой вопрос: « :inputСелектор в основном выбирает все элементы управления формы. Выбирает все элементы ввода, текстовой области, выбора и кнопки». источник
Dinei

Да, у Тома сломан . Твой чище, чем моя попытка на этой скрипке. Up'd
Hashbrown

11

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

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();

Что ж, обратный вызов позволяет передавать значения, возвращающие истину, !!повторно набирает все на bool, вы можете попробовать в консоли. !!('test'), !!(5),!!(0)
Aiphee

2
И вместо inputселектора нужно :inputвключать
выборки

Я предлагаю это изменение:data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize();
Mahoor13

9

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

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

.replace (/[^&pting+=\.?(& | $) / g, '') охватывает оба случая. Но я бы добавил .replace (/ & $ /, ''), чтобы удалить завершающий &
Том Винер

15
Нет проблемы, что регулярное выражение не может сделать хуже.
Майкл Кук

3

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

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

Может быть кому-то полезно


1

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

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

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

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


1

Альтернатива решению Рича :

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

Пояснения:

  • .submit()подключается к submitсобытию формы
  • e.preventDefault() предотвращает отправку формы
  • .serializeArray() дает нам представление в виде массива строки запроса, которая должна была быть отправлена.
  • .filter() удаляет ложные (включая пустые) значения в этом массиве.
  • $.param(query) создает сериализованное и совместимое с URL-адресом представление нашего обновленного массива
  • установка значения для window.location.hrefотправки запроса

0

В coffeescript сделайте следующее:

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

-1

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


1
Единственная проблема с этим состоит в том, что пользователь увидит, что пустые элементы управления исчезают непосредственно перед отправкой страницы. Было бы лучше установить имя "", чтобы сериализация игнорировала его.
Tom Viner
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.