Jak przekonwertować wszystkie elementy mojego formularza na obiekt JavaScript?
Chciałbym mieć jakiś sposób automatycznego budowania obiektu JavaScript z mojej formy, bez konieczności zapętlania każdego elementu. Nie chcę ciągu w postaci zwróconej przez $('#formid').serialize();
, ani nie chcę, aby mapa została zwrócona przez$('#formid').serializeArray();
javascript
jquery
json
serialization
Yisroel
źródło
źródło
Odpowiedzi:
serializeArray
już to robi. Musisz tylko zamasować dane do wymaganego formatu:Uważaj na ukryte pola, które mają taką samą nazwę jak rzeczywiste dane wejściowe, ponieważ zostaną zastąpione.
źródło
$.map( $("#container :input"), function(n, i) { /* n.name and $(n).val() */ } );
jeśli chcesz uwzględnić wyłączone elementy.foo[bar]
danych wejściowych typu zgodnie z oczekiwaniami, nie wspominając o większości innych odmian nazw wejściowych. Po bardzo frustracji płytkimi rozwiązaniami tego problemu napisałem własną wtyczkę jQuery - szczegóły w odpowiedzi, której udzieliłem na to pytanie.Konwertuj formularze na JSON jak szef
Obecne źródło znajduje się na GitHub i Bower .
Poniższy kod jest już nieaktualny .
Poniższy kod może zająć się wszystkimi rodzajami nazw wejściowych; i obchodź się z nimi tak, jak można się spodziewać.
Na przykład:
Stosowanie
The Sorcery (JavaScript)
źródło
<select name="foo" multiple="multiple">
nie będzie działać w żadnym scenariuszu. Jeśli jednak użyjesz[]
, jak w<select name="bar[]" multiple="multiple">
, to będzie działać dobrze :)Co jest źle z:
źródło
.each
zamiast.map
??var form = {}; $.each($(this).serializeArray(), function (i, field) { form[field.name] = field.value || ""; });
$(this).serializeArray().reduce(function(m,o){ m[o.name] = o.value; return m;}, {})
Naprawiona wersja rozwiązania Tobiasa Cohena. Ten poprawnie obsługuje wartości fałszowania, takie jak
0
i''
.Oraz wersja CoffeeScript dla Twojej wygody kodowania:
źródło
value = @value ? ''
keyMap
i następujący wiersz:key = if keyMap? then keyMap(@name) else @name
. Teraz możesz przekazać funkcję mapowania jak(name) -> name.match(/\[([^\]]+)]/)[1]
. I wtedy należałoby zmienić wszystkie późniejsze@name
celukey
, oczywiściepost
, możesz po prostu to zrobić$('form').serializeObject().post
. Nie ma potrzeby wymyślnego mapowania.if (!objectData[this.name].push)
??objectData[this.name]
ma metodę push (z grubsza, czy jest to tablica). Jeśli jest to tablica, wypycha wartość, jeśli nie jest tablicą, konwertuje ją na tablicę, dzięki czemu wiele wartości z tym samym kluczem zostanie połączonych w tablicę.Lubię używać,
Array.prototype.reduce
ponieważ jest to jedna linijka i nie opiera się na Underscore.js lub podobnym:Jest to podobne do użycia odpowiedzi
Array.prototype.map
, ale nie musisz zaśmiecać swojego zasięgu dodatkową zmienną obiektową. One-stop shopping.WAŻNA UWAGA : Formularze z danymi wejściowymi, które mają zduplikowane
name
atrybuty, są poprawnymi kodami HTML i są w rzeczywistości powszechnym podejściem. W takim przypadku użycie dowolnej odpowiedzi w tym wątku będzie nieodpowiednie (ponieważ klucze obiektów muszą być unikalne).źródło
array.prototype.reduce()
nie jest dostępny w IE8, ponieważ jest częścią specyfikacji ECMAScript 5. Więc jeśli potrzebujesz wsparcia IE8, będziesz chciał użyć polifillu lub innego rozwiązania.Wszystkie te odpowiedzi wydawały mi się przesadne. Jest coś, co można powiedzieć o prostocie. Dopóki wszystkie dane wejściowe formularza mają ustawiony atrybut name, powinno to działać po prostu Jim Dandy.
źródło
Naprawdę nie ma takiej możliwości bez zbadania każdego z elementów. To, co naprawdę chcesz wiedzieć, to „czy ktoś już napisał metodę, która konwertuje formularz na obiekt JSON?” Powinno działać coś podobnego - zwróć uwagę, że da ci tylko elementy formularza, które zostaną zwrócone za pomocą POST (musi mieć nazwę). To nie jest testowane .
źródło
Jeśli używasz Underscore.js , możesz użyć stosunkowo zwięzłego:
źródło
Sprawdziłem, że istnieje problem ze wszystkimi pozostałymi odpowiedziami, że jeśli nazwa wejściowa ma postać tablicy, na przykład
name[key]
, to powinna zostać wygenerowana w następujący sposób:name:{ key : value }
Na przykład: jeśli masz formularz HTML podobny do poniższego:
Ale powinien być generowany tak jak JSON poniżej i nie staje się obiektem podobnym do poniższego ze wszystkimi innymi odpowiedziami. Więc jeśli ktoś chce przynieść coś takiego jak następujący JSON, wypróbuj poniższy kod JS.
źródło
eval
nie należy go używać w ten sposób, ponieważeval
w ten sposób promuje strasznie niewiarygodne, błędne, źle działające i potencjalnie niebezpieczne praktyki.this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
jest krótki i niewytłumaczalny. Dev z mniejszym doświadczeniem skopiuje to bez zrozumienia, dlaczego i jak to działa.eval()
z mojego kodu.Ok, wiem, że ma to już bardzo pozytywną odpowiedź, ale zadano inne podobne pytanie ostatnio i skierowano mnie również na to pytanie. Chciałbym również zaoferować moje rozwiązanie, ponieważ ma ono przewagę nad zaakceptowanym rozwiązaniem: możesz dołączyć wyłączone elementy formularza (co jest czasami ważne, w zależności od tego, jak działa Twój interfejs użytkownika)
Oto moja odpowiedź na inne SO pytanie :
Początkowo używaliśmy metody jQuery
serializeArray()
, ale nie obejmuje ona elementów formularza, które są wyłączone. Często wyłączamy elementy formularza, które są „synchronizowane” z innymi źródłami na stronie, ale nadal musimy uwzględnić dane w naszym serializowanym obiekcie. TakserializeArray()
jest. Użyliśmy:input
selektora, aby uzyskać wszystkie elementy wejściowe (zarówno włączone, jak i wyłączone) w danym kontenerze, a następnie$.map()
stworzyć nasz obiekt.Zauważ, że aby to zadziałało, każde twoje wejście będzie wymagało
name
atrybutu, który będzie nazwą właściwości wynikowego obiektu.To jest właściwie nieco zmodyfikowane w stosunku do tego, z czego korzystaliśmy. Musieliśmy utworzyć obiekt o strukturze .NET IDictionary, więc użyliśmy tego: (Podaję go tutaj, na wypadek, gdyby był użyteczny)
Podobają mi się oba te rozwiązania, ponieważ są one prostymi zastosowaniami
$.map()
funkcji, a ty masz pełną kontrolę nad swoim selektorem (więc jakie elementy trafisz w tym do wynikowego obiektu). Ponadto nie jest wymagana dodatkowa wtyczka. Zwykły stary jQuery.źródło
map
tego w taki sposób tworzy tablicę obiektów z pojedynczą właściwością, to nie powoduje zwinięcia wszystkich właściwości w jeden obiekt.Ta funkcja powinna obsługiwać tablice wielowymiarowe wraz z wieloma elementami o tej samej nazwie.
Używam go od kilku lat:
źródło
Możesz to zrobić:
Zobacz JSON .
źródło
Jednoliniowy (bez zależności innych niż jQuery), używa stałego wiązania obiektu dla funkcji przekazywanej do
map
metody.Co to robi?
nadaje się do progresywnych aplikacji internetowych (z łatwością można obsługiwać zarówno zwykłe przesyłanie formularzy, jak i żądania ajax)
źródło
Posługiwać się:
Wynik:
źródło
Prostota jest tutaj najlepsza. Użyłem prostego łańcucha zastępującego wyrażenie regularne i do tej pory działały jak urok. Nie jestem ekspertem od wyrażeń regularnych, ale założę się, że możesz zapełniać nawet bardzo złożone obiekty.
źródło
Od jakiejś starszej odpowiedzi:
źródło
serializeArray
tego, więc masz swobodę wyboru dowolnych wejść (np. Możesz włączyć wejścia wyłączone), prawda? Czyli nie jest to powiązane z żadną formą ani zdarzeniem przesyłania, jest po prostu samo w sobie niezależne?reduce
zwraca obiekt. Nie jest to niezależne, ponieważtoArray
pochodzi z jQuery.Znalazłem problem z kodem Tobiasza Cohena (nie mam wystarczającej liczby punktów, aby go skomentować bezpośrednio), co w innym przypadku działa dla mnie. Jeśli masz dwie opcje wyboru o tej samej nazwie, obie o wartości = „”, oryginalny kod wygeneruje „name”: „” zamiast „name”: [”„, ””]
Myślę, że można to naprawić, dodając „|| o [this.name] == ''” do pierwszego, jeśli warunek:
źródło
Korzystając z rozwiązania Mačka , zmodyfikowałem go, aby działał w sposób, w jaki ASP.NET MVC obsługuje swoje zagnieżdżone / złożone obiekty w tej samej formie. Wszystko, co musisz zrobić, to zmodyfikować poprawny fragment do tego:
Spowoduje to dopasowanie, a następnie prawidłowe odwzorowanie elementów o nazwach takich jak:
I
źródło
najprostszy i najdokładniejszy sposób znalazłem tego problemu było zastosowanie wtyczki grilla lub ten jeden (który jest o 0.5K bajtów rozmiar).
działa również z tablicami wielowymiarowymi.
źródło
Jest taka wtyczka do jQuery, jquery.serializeJSON . Z powodzeniem wykorzystałem go w kilku projektach. To działa jak urok.
źródło
źródło
Wolę takie podejście, ponieważ: nie musisz iterować ponad 2 kolekcje, możesz uzyskać inne rzeczy niż „nazwa” i „wartość”, jeśli to konieczne, i możesz zdezynfekować swoje wartości przed zapisaniem ich w obiekcie ( jeśli masz na przykład wartości domyślne, których nie chcesz przechowywać).
Użyj tak:
Testowane tylko w przeglądarce Firefox.
źródło
Zamień wszystko w obiekt (nie testowany jednostkowo)
Wynik testu:
na
da:
źródło
Znalazłem problem z wybranym rozwiązaniem.
Podczas korzystania z formularzy, które mają nazwy oparte na tablicach, funkcja serializeArray () jQuery faktycznie umiera.
Mam framework PHP, który używa tablicowych nazw pól, aby umożliwić wielokrotne umieszczanie tej samej formy na tej samej stronie w wielu widokach. Może to być przydatne do dodawania, edytowania i usuwania na tej samej stronie bez sprzecznych modeli formularzy.
Ponieważ chciałem seralizować formularze bez konieczności wyłączania tej absolutnej podstawowej funkcjonalności, postanowiłem napisać własną seralizeArray ():
Uwaga: Działa to również poza formularzem submission (), więc jeśli wystąpi błąd w pozostałej części kodu, formularz nie zostanie przesłany, jeśli umieścisz przycisk linku z napisem „zapisz zmiany”.
Należy również pamiętać, że tej funkcji nie należy nigdy używać do sprawdzania poprawności formularza tylko w celu zebrania danych do wysłania po stronie serwera w celu sprawdzenia poprawności. Użycie takiego słabego i przypisanego masowo kodu spowoduje XSS itp.
źródło
Miałem ostatnio ten sam problem i wypuściłem wtyczkę .toJSON jQuery, która konwertuje formularz na obiekt JSON o tej samej strukturze. Jest to szczególnie przydatne w przypadku dynamicznie generowanych formularzy, w których użytkownik chce, aby użytkownik dodawał więcej pól w określonych miejscach.
Chodzi o to, że możesz chcieć zbudować formularz tak, aby sam miał strukturę, więc powiedzmy, że chcesz stworzyć formularz, w którym użytkownik wstawi swoje ulubione miejsca w mieście: możesz sobie wyobrazić, że ten formularz reprezentuje
<places>...</places>
element XML zawierający lista miejsc, które użytkownik lubi, a zatem lista<place>...</place>
elementów, z których każda zawiera na przykład<name>...</name>
element,<type>...</type>
element, a następnie listę<activity>...</activity>
elementów reprezentujących czynności, które można wykonać w takim miejscu. Twoja struktura XML wyglądałaby tak:Jak fajnie byłoby mieć z tego obiekt JSON, który reprezentowałby tę dokładną strukturę, abyś mógł:
OK, teraz musimy pomyśleć, jak formularz może reprezentować plik XML.
Oczywiście
<form>
znacznik jestroot
, ale mamy ten<place>
element, który jest kontenerem, a nie samym elementem danych, więc nie możemy dla niego użyć znacznika wejściowego.Oto, gdzie
<fieldset>
przydaje się tag! Użyjemy<fieldset>
znaczników do reprezentowania wszystkich elementów kontenera w naszej reprezentacji formularza / XML, aby uzyskać taki wynik:Jak widać w tym formularzu, łamiemy zasadę unikatowych nazw, ale jest to w porządku, ponieważ zostaną przekonwertowane na tablicę elementu, a więc będą się do nich odwoływały tylko ich indeksy wewnątrz tablicy.
W tym momencie możesz zobaczyć, jak
name="array[]"
w formularzu nie ma podobnej nazwy, a wszystko jest ładne, proste i semantyczne.Teraz chcemy, aby ten formularz został przekonwertowany na obiekt JSON, który będzie wyglądał następująco:
Aby to zrobić, opracowałem tutaj wtyczkę jQuery, którą ktoś pomógł zoptymalizować w tym wątku Code Review i wygląda następująco:
Napisałem też ten post na blogu, aby wyjaśnić to więcej.
Konwertuje to wszystko w formie do JSON (nawet radio i pola wyboru) i wszystko, co pozostało do zrobienia, to połączenie
Wiem, że istnieje wiele sposobów konwertowania formularzy na obiekty JSON,
.serialize()
ale.serializeArray()
w większości przypadków działają one doskonale i są przeznaczone głównie do użycia, ale myślę, że cała ta idea pisania formularza jako struktury XML o znaczących nazwach i przekształcania go w dobrze sformułowany obiekt JSON jest warty wypróbowania, a także fakt, że można bez obaw dodawać tagi wejściowe o tej samej nazwie, jest bardzo przydatny, jeśli trzeba pobrać dane formularzy generowane dynamicznie.Mam nadzieję, że to komuś pomoże!
źródło
Sam kodowałem formularz do wielowymiarowego obiektu JavaScript, aby użyć go w środowisku produkcyjnym. Wynikiem jest https://github.com/serbanghita/formToObject.js .
źródło
Kolejna odpowiedź
FormData: https://developer.mozilla.org/en-US/docs/Web/API/FormData
źródło
[AKTUALIZACJA 2020]
Z prostym oneliner w waniliowym js:
źródło
Podoba mi się wersja samuels, ale uważam, że ma mały błąd. Zwykle JSON jest wysyłany jako
NIE jak
więc funkcja IMO powinna brzmieć:
i aby zawinąć go w tablicę danych (jak się powszechnie oczekuje), a na koniec wysłać jako ciąg aplikacji App.stringify ({data: App.toJson ('#cropform: input')})
Aby zapoznać się ze strantyfikacją, patrz pytanie 3593046 dla wersji lean, json2.js dla wersji na każdą ewentualność. To wszystko powinno obejmować :)
źródło
Aby uzyskać szybkie, nowoczesne rozwiązanie, użyj wtyczki JSONify jQuery. Poniższy przykład został zaczerpnięty dosłownie z GITHub README. Podziękowania dla Kushal Pandya, autora wtyczki.
Dany:
Bieganie:
Produkuje:
Jeśli chcesz wykonać test POST jQuery z tym obiektem JSON:
źródło