Як використовувати jQuery's 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 отримує елемент з id "myForm", але те, що мені спочатку було менш очевидним, - це те, що потрібний пробільний символ між #myForm та: input, оскільки це оператор- нащадок .

: введення відповідає всім елементам введення, текстовій області, елементам вибору та кнопок.

[value! = ''] є атрибутом, не рівним фільтру. Дивна (і корисна) річ у тому, що все: введення типи елементів мають атрибути значення, навіть вибрані та прапорці тощо.

Нарешті, також видалити вхідні дані, де було значення "." (як зазначено у питанні):

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

У цьому випадку супозиція, тобто розміщення двох селекторів атрибутів поруч один з одним , означає І. Використання коми означає ІЛИ. Вибачте, якщо це очевидно для людей CSS!


3
@Mvision, це тому, що в цій відповіді є невеликий, але суттєвий недолік. Для звичайних / чистих CSS-селекторів у jQuery 1.8 та новіших версіях [value]збігається з будь-яким елементом із value наявним атрибутом , у тому числі з порожніми (або відсутніми) значеннями. Це пов’язано з помилкою у попередніх версіях jQuery, яка створила невідповідність між певними варіаціями input[value]та :input[value]. Візьмемо, наприклад <input value="foo"><input value=""><input value><input>,; помилка проілюстрована в цій скрипці .
Нойо

4
Для мене це спрацювало: $form.find(":input[value]")- порожні поля не були вибрані. Це не спрацювало: $form.find(":input[value!='']")- вибрано всі поля. Сподіваюся, що хтось допомагає. (jQuery 2.0.0)
Ryan Wheale

1
$form.find(":input[value]")також працював для мене (jQuery 1.11.0)
GSTAR

Працював лише, якщо valueатрибут вже був. Це не визнало інакше.
зірковий

1
У деяких випадках, коли valueвстановлено програмно, це не буде працювати ( valueне буде як атрибут HTML, але буде атрибутом даних на вході). У тих випадках, спробуйте наступне: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). EDIT: Щойно побачив відповідь Річа на той же ефект.
Фатех Халса

54

Я не зміг заставити рішення Тома працювати (?), Але мені вдалося це зробити за .filter()допомогою короткої функції для визначення порожніх полів. Я використовую jQuery 2.1.1.

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

2
Не вдалося отримати схвалену відповідь на роботу, але це спрацювало чудово! Дякую!
bfritz

Відповідаючи на моє власне запитання: " :inputСелектор в основному вибирає всі елементи керування форми. Вибирає всі елементи введення, текстові області, елементи вибору та кнопки". джерело
Діней

Так, Том зламаний . Ваша чистіша, ніж моя спроба в цій скрипці теж. 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 (/ evidence^&Sense+=\.?(& | $) / g, '') охоплює обидва випадки. Але я б додав .замінити (/ & $ /, '') для видалення задніх &
Том Вінер

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
Єдина проблема з цим полягає в тому, що користувач побачить, як порожнє з елементів управління зникне перед подачею сторінки. Краще встановити ім'я "", щоб серіалізація ігнорувала його.
Том Вінер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.