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:
<places>
<place>
<name>Home</name>
<type>dwelling</type>
<activity>sleep</activity>
<activity>eat</activity>
<activity>watch TV</activity>
</place>
<place>...</place>
<place>...</place>
</places>
Jak fajnie byłoby mieć z tego obiekt JSON, który reprezentowałby tę dokładną strukturę, abyś mógł:
- Przechowuj ten obiekt tak, jak jest w dowolnej bazie danych podobnej do CouchDB
- Przeczytaj go po stronie serwera $ _POST [] i pobierz poprawnie zagnieżdżoną tablicę, którą możesz następnie modyfikować semantycznie
- Użyj jakiegoś skryptu po stronie serwera, aby przekonwertować go na dobrze sformatowany plik XML (nawet jeśli nie znasz jego dokładnej struktury a priori)
- Po prostu użyj go tak, jak jest w dowolnym skrypcie serwera podobnym do Node.js
OK, teraz musimy pomyśleć, jak formularz może reprezentować plik XML.
Oczywiście <form>
znacznik jest root
, 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:
<form name="places">
<fieldset name="place">
<input type="text" name="name"/>
<select name="type">
<option value="dwelling">Dwelling</option>
<option value="restoration">Restoration</option>
<option value="sport">Sport</option>
<option value="administrative">Administrative</option>
</select>
<input type="text" name="activity"/>
<input type="text" name="activity"/>
<input type="text" name="activity"/>
</fieldset>
</form>
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:
{'places':{
'place':[
{
'name': 'Home',
'type': 'dwelling',
'activity':[
'sleep',
'eat',
'watch TV'
]
},
{...},
{...}
]
}}
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:
$.fn.toJSO = function () {
var obj = {},
$kids = $(this).children('[name]');
if (!$kids.length) {
return $(this).val();
}
$kids.each(function () {
var $el = $(this),
name = $el.attr('name');
if ($el.siblings("[name=" + name + "]").length) {
if (!/radio|checkbox/i.test($el.attr('type')) || $el.prop('checked')) {
obj[name] = obj[name] || [];
obj[name].push($el.toJSO());
}
} else {
obj[name] = $el.toJSO();
}
});
return obj;
};
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
$.post('script.php',('form').toJSO(), ...);
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!