Jak używać form.serialize jQuery z wykluczeniem pustych pól

107

Mam formularz wyszukiwania z wieloma danymi wejściowymi i rozwijanymi, które przesyła za pośrednictwem GET. Chciałbym mieć bardziej przejrzysty adres URL wyszukiwania, usuwając puste pola z kwerendy podczas wyszukiwania.

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

Masz jakiś pomysł, jak mogę to zrobić za pomocą jQuery?

Tom Viner
źródło

Odpowiedzi:

167

Przeglądałem dokumentację jQuery i myślę, że możemy to zrobić w jednej linii za pomocą selektorów :

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

Oczywiście #myForm pobiera element o identyfikatorze „myForm”, ale na początku mniej oczywiste było dla mnie to, że znak spacji jest potrzebny między #myForm a: input, ponieważ jest to operator potomka .

: input pasuje do wszystkich elementów input, textarea, select i button.

[wartość! = ''] nie jest równym filtrem atrybutu. Dziwne (i pomocne) jest to, że wszystkie typy elementów wejściowych mają atrybuty wartości, a nawet zaznaczenia i pola wyboru itp.

Wreszcie, aby usunąć również dane wejściowe, w których wartość wynosiła „.” (jak wspomniano w pytaniu):

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

W tym przypadku zestawienie, tj. Umieszczenie obok siebie dwóch selektorów atrybutów , implikuje AND. Użycie przecinka implikuje OR. Przepraszam, jeśli to oczywiste dla ludzi CSS!

Tom Viner
źródło
3
@Mvision, to dlatego, że w tej odpowiedzi jest małe, ale znaczące pominięcie. W przypadku zwykłych / czystych selektorów CSS w jQuery 1.8 i wcześniejszych, [value]dopasowuje dowolny element z value obecnym atrybutem , w tym te z pustymi wartościami (lub bez). Wynika to z błędu we wcześniejszych wersjach jQuery, który spowodował niespójność między niektórymi odmianami input[value]i :input[value]. Weźmy na przykład <input value="foo"><input value=""><input value><input>; błąd jest zilustrowany na tych skrzypcach .
Noyo
4
U mnie to zadziałało: $form.find(":input[value]")- puste pola nie zostały wybrane. To nie zadziałało: $form.find(":input[value!='']")- wszystkie pola zostały wybrane. Mam nadzieję, że to komuś pomoże. (jQuery 2.0.0)
Ryan Wheale
1
$form.find(":input[value]")również pracował dla mnie (jQuery 1.11.0)
GSTAR
Działało tylko wtedy, gdy valueatrybut już tam był. Inaczej tego nie rozpoznał.
starcorn
1
W niektórych przypadkach, gdy valuejest ustawiany programowo, to nie zadziała ( valuenie będzie istnieć jako atrybut HTML, ale będzie jako atrybut danych na wejściu). W tych przypadkach, spróbuj tego: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). EDYCJA: Właśnie zobaczyłem odpowiedź Richa na ten sam efekt.
Fateh Khalsa
54

Nie byłem w stanie zmusić rozwiązania Toma do działania (?), Ale udało mi się to zrobić za .filter()pomocą krótkiej funkcji do identyfikacji pustych pól. Używam jQuery 2.1.1.

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();
Bogaty
źródło
2
Nie udało się uzyskać zatwierdzonej odpowiedzi, ale zadziałało świetnie! Dzięki!
bfritz
Odpowiadając na moje własne pytanie: „ :inputSelektor zasadniczo wybiera wszystkie kontrolki formularza. Zaznacza wszystkie elementy wejściowe, tekstowe, zaznaczania i przyciski”. źródło
Dinei
Tak, Tom's jest zepsuty . Twoje jest czystsze niż moja próba gry na skrzypcach. Up'd
Hashbrown
11

To działa dla mnie:

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();
RMazitov
źródło
Cóż, !!funkcja zwrotna pozwala przekazywać wartości zwracające prawdę, przepisuje wszystko na bool, możesz spróbować w konsoli. !!('test'), !!(5),!!(0)
Aiphee
2
I zamiast inputselektora powinno być :inputwłączanie
selekcji
Proponuję taką zmianę:data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize();
Mahoor 13
9

Możesz to zrobić za pomocą wyrażenia regularnego ...

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

Przypadki testowe:

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
nickf
źródło
.replace (/[^&]+=\.?(& | $) / g, '') obejmuje oba przypadki. Ale dodałbym .replace (/ & $ /, ''), aby usunąć końcowe &
Tom Viner,
15
Nie ma problemu, którego regex nie może pogorszyć.
Michael Cook
3

Użyłem powyższego rozwiązania, ale u mnie te nie zadziałały. Więc użyłem następującego kodu

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

Może się komuś przydać

Rajan Rawal
źródło
1

Spojrzałbym na kod źródłowy jQuery. W najnowszej wersji linia 3287.

Mógłbym dodać funkcje „serialize2” i „serializeArray2”. oczywiście nazwij ich coś podłego.

Lub lepszym sposobem byłoby napisanie czegoś, co spowoduje wyciągnięcie nieużywanych zmiennych z serializedFormStr. Jakieś wyrażenie regularne szukające = & w środku ciągu lub kończące się na = Czy są w pobliżu jakieś kreatory wyrażeń regularnych?

AKTUALIZACJA: Bardziej podoba mi się odpowiedź rogeriopvl (+1) ... zwłaszcza, że ​​nie mogę teraz znaleźć żadnych dobrych narzędzi do wyrażeń regularnych.

BuddyJoe
źródło
1

Alternatywa dla rozwiązania Richa :

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

Objaśnienia:

  • .submit() zaczepia się o formularz submit zdarzenie
  • e.preventDefault() uniemożliwia przesłanie formularza
  • .serializeArray() daje nam tablicę reprezentującą ciąg zapytania, który miał zostać wysłany.
  • .filter() usuwa fałszywe (w tym puste) wartości z tej tablicy.
  • $.param(query) tworzy serializowaną i zgodną z adresem URL reprezentację naszej zaktualizowanej tablicy
  • ustawienie wartości do window.location.hrefwysłania żądania
Kathandrax
źródło
0

W Coffeescript zrób to:

serialized_form = $(_.filter($(context).find("form.params input"), (x) -> $(x).val() != '')).serialize()
John Goodsen
źródło
-1

Możesz zajrzeć do funkcji .each () jquery, która pozwala na iterację przez każdy element selektora, więc w ten sposób możesz sprawdzić każde pole wejściowe i zobaczyć, czy jest puste, czy nie, a następnie usunąć je z formularza przy użyciu elementu.remove (). Następnie możesz serializować formularz.

rogeriopvl
źródło
1
Jedynym problemem jest to, że użytkownik zobaczy puste elementy kontrolne znikające tuż przed przesłaniem strony. Lepiej byłoby ustawić nazwę na „”, więc serializacja ją ignoruje.
Tom Viner,