How do I convert all elements of my form to a JavaScript object?
I'd like to have some way of automatically building a JavaScript object from my form, without having to loop over each element. I do not want a string, as returned by $('#formid').serialize();
, nor do I want the map returned by $('#formid').serializeArray();
I like samuels version, but I believe it has a small error. Normally JSON is sent as
NOT as
so the function IMO should read:
and to wrap it in data array (as commonly expected, too), and finally send it as astring App.stringify( {data:App.toJson( '#cropform :input' )} )
For the stringify look at Question 3593046 for the lean version, at json2.js for the every-eventuality-covered version. That should cover it all :)
I found a problem with the selected solution.
When using forms that have array based names the jQuery serializeArray() function actually dies.
I have a PHP framework that uses array-based field names to allow for the same form to be put onto the same page multiple times in multiple views. This can be handy to put both add, edit and delete on the same page without conflicting form models.
Since I wanted to seralize the forms without having to take this absolute base functionality out I decided to write my own seralizeArray():
Please note: This also works outside of form submit() so if an error occurs in the rest of your code the form won't submit if you place on a link button saying "save changes".
Also note that this function should never be used to validate the form only to gather the data to send to the server-side for validation. Using such weak and mass-assigned code WILL cause XSS, etc.
Convert forms to JSON LIKE A BOSS
Current source is on GitHub and bower.
The following code is now deprecated.
The following code can take work with all sorts of input names; and handle them just as you'd expect.
For example:
Usage
The Sorcery (JavaScript)
I like using
Array.prototype.reduce
because it's a one-liner, and it doesn't rely on Underscore.js or the like:This is similar to the answer using
Array.prototype.map
, but you don't need to clutter up your scope with an additional object variable. One-stop shopping.IMPORTANT NOTE: Forms with inputs that have duplicate
name
attributes are valid HTML, and is actually a common approach. Using any of the answers in this thread will be inappropriate in that case (since object keys must be unique).This function should handle multidimensional arrays along with multiple elements with the same name.
I've been using it for a couple years so far:
I had the same problem lately and came out with this .toJSON jQuery plugin which converts a form into a JSON object with the same structure. This is also expecially useful for dynamically generated forms where you want to let your user add more fields in specific places.
The point is you may actually want to build a form so that it has a structure itself, so let's say you want to make a form where the user inserts his favourite places in town: you can imagine this form to represent a
<places>...</places>
XML element containing a list of places the user likes thus a list of<place>...</place>
elements each one containing for example a<name>...</name>
element, a<type>...</type>
element and then a list of<activity>...</activity>
elements to represent the activities you can perform in such a place. So your XML structure would be like this:How cool would it be to have a JSON object out of this which would represent this exact structure so you'll be able to either:
OK, so now we need to think how a form can represent an XML file.
Of course the
<form>
tag is theroot
, but then we have that<place>
element which is a container and not a data element itself, so we cannot use an input tag for it.Here's where the
<fieldset>
tag comes in handy! We'll use<fieldset>
tags to represent all container elements in our form/XML representation and so getting to a result like this:As you can see in this form, we're breaking the rule of unique names, but this is OK because they'll be converted into an array of element thus they'll be referenced only by their index inside the array.
At this point you can see how there's no
name="array[]"
like name inside the form and everything is pretty, simple and semantic.Now we want this form to be converted into a JSON object which will look like this:
To do this I have developed this jQuery plugin here which someone helped optimizing in this Code Review thread and looks like this:
I also made this one blog post to explain this more.
This converts everything in a form to JSON (even radio and check boxes) and all you'll have left to do is call
I know there's plenty of ways to convert forms into JSON objects and sure
.serialize()
and.serializeArray()
work great in most cases and are mostly intended to be used, but I think this whole idea of writing a form as an XML structure with meaningful names and converting it into a well-formed JSON object is worth the try, also the fact you can add same-name input tags without worrying is very useful if you need to retrive dynamically generated forms data.I hope this helps someone!