25 Answers
25

Close, but perhaps something that returns an array with key-value pairs instead of a single string?
– Bart van HeukelomFeb 16 '10 at 21:28

69

Nvm, found it in the comments for the serialize() function. It's called serializeArray. It returns an array of arrays (which contain an entry "name" and "value") but that should be easy enough to transform.
– Bart van HeukelomFeb 16 '10 at 21:33

serializeArray would be so much more useful if it returned an object with key-value pairs
– GetFreeOct 2 '13 at 19:44

4

I agree that an object would be ideal. However, there is a problem - a key is allowed to have multiple values. Would you return a key-"array of values" object, or key-"first value" or something else? I think jQuery guys chose none of the above :)
– PaulOct 9 '13 at 6:25

Be aware of a problem with multiple values (as @Paul mentioned above), checkboxes and multiple inputs with name="multiple[]" do not work. The solution for POST method is the same, just use $('form').serialize(). Also the POST method does not have limit of 2000 characters as GET does in most browsers, so can be used even for a pretty large data.
– ArtruSep 17 '16 at 8:51

Please also beware that in order to record a value from any form input, the input must have a name attribute.
– Chris - JrOct 27 '17 at 19:37

Keep in mind FormData is part of the XMLHttpRequest advanced features (previously known as XMLHttpRequest Level 2) so you must rely on a polyfill for Internet Explorer < 10. caniuse.com/#feat=xhr2
– Pier-Luc GendreauJun 15 '15 at 23:18

1

@yochannah, not so. Sure, one can't simply access and edit the data like a normal object, but it is still trivial to get the data. Check out the entries() method [MDN page].
– Web and FlowSep 17 '16 at 16:36

@Web and Flow thanks for pointing this out! I love it when browsers add new and useful features :) times, they are a-changing.
– yochannahSep 18 '16 at 7:55

I'm trying to use FormData to send an object to my Flask-python script, but it doesn't seem to be coming over as a normal request object that I can unpack. Can someone point to an explanation of any special steps to handle it on the server side? That's where it seems empty to me.
– manishaNov 15 '16 at 20:41

document.querySelector('form').addEventListener('submit', (e) => {
const formData = new FormData(e.target);
// Now you can use formData.get('foo'), for example.
// Don't forget e.preventDefault() if you want to stop normal form .submission
});

This is a nitpicky answer, but let me explain why this is a better solution:

We're properly handling a form submit rather than a button press. Some people like to push enter on fields. Some people use alternative input devices such as speech input or other accessibility devices. Handle the form submit and you correctly solve it for everyone.

We're digging into the form data for the actual form that was submitted. If you change your form selector later, you don't have to change the selectors for all the fields. Furthermore, you might have several forms with the same input names. No need to disambiguate with excessive IDs and what not, just track the inputs based on the form that was submitted. This also enables you to use a single event handler for multiple forms if that is appropriate for your situation.

The FormData interface is fairly new, but is well supported by browsers. It's a great way to build that data collection to get the real values of what's in the form. Without it, you're going to have to loop through all the elements (such as with form.elements) and figure out what's checked, what isn't, what the values are, etc. Totally possible if you need old browser support, but the FormData interface is simpler.

I'm using ES6 here... not a requirement by any means, so change it back to be ES5 compatible if you need old browser support.

@Blauhirn Nonsense, of course they expose the values. The code in my answer works. You should try it. Here, I made a fiddle for you: jsfiddle.net/zv9s1xq5 If you want an iterator, use formData.entries().
– BradNov 24 '18 at 13:14

I know it works, but the properties are not accessible by key. For example, formData.foo is undefined. As seen in your answer, .get() needs to be called for that which I think is inconvenient. Maybe "does not expose" came accross the wrong way. So, to generate something like { foo: 'bar' } from a submit event, you need to iterate over them manually. Hence the . To get a plain object from it, see [link].
– BlauhirnNov 24 '18 at 13:56

@Blauhirn As I just mentioned, if you want an iterator, use .entries(). Also, don't forget that forms can contain multiple fields with the same name, so you must handle somehow that if you want a plain object. The iterator approach is better.
– BradNov 24 '18 at 14:50

This overwrites my checkboxes if I have something like <input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />. If both are checked, the object only contains the second checkbox value.
– dmathisenJan 11 '15 at 22:43

2

Isn't this a case where someList should be type="radio"?
– dylanjameswagnerJan 14 '15 at 16:46

Note that this plugin doesn't work for cases where multiple form input entries with the same name are present. The last entry would replace the previous one whereas the expected behavior would be to get all the values as an Array
– MilliJun 8 '17 at 18:45

Just a note that a year later I now think this is a terrible answer and no one should use it. As the previous comment says, things like radio buttons would not work. There are better answers above, use one of those instead.
– Dustin PoissantSep 26 '17 at 14:09

edit:

If you're looking for a more complete implementation, then take a look at this section of the project I made this for. I'll update this question eventually with the complete solution I came up with, but maybe this will be helpful to someone.

Nice solution :) I did find one bug though, with the setOrPush function. It does not include a check to see whether target is already an array, causing the creation of a deep nested array in case of multiple checked checkboxes with the same name.
– Wouter van DamMay 30 '17 at 22:19

@KyleFalconer Nice! Why didn't you merge the switch cases for radio and checkbox -- they will work correctly (I am guess).
– EthanJun 30 '17 at 23:41

@Ethan It's because a checkbox can have multiple values selected and a radio can only ever have one value selected, so the way I store the value changes.
– Kyle FalconerJul 3 '17 at 16:59

@KyleFalconer Yes, I understand that. The code for handling 'checkbox' also takes care of the single possible choice for 'radio', by virtue of the 'SetOrPush' routine.
– EthanJul 6 '17 at 0:22

@Ethan Oh I think I know what you're saying. It could be done either way, but I think I did it this way just because I wanted just one value, not an array of values.
– Kyle FalconerJul 7 '17 at 18:46

You can also use the FormData Objects; The FormData object lets you compile a set of key/value pairs to send using XMLHttpRequest. Its primarily intended for use in sending form data, but can be used independently from forms in order to transmit keyed data.

Thanks, but what if you don't have ID? What if you have a form as JQuery object? var form = $(this).closest('form'); ? Should var formElement = document.getElementById(form[0]); work instead your firs line? Well it is not working, unfortunately. Do you know why?
– Yevgeniy AfanasyevNov 9 '15 at 1:55

Actually the FormData is not supported by all browsers :( so better use a different approach
– numediawebNov 9 '15 at 9:41

Thanks. I used latest chrome and still it was not working. So I went with #neuront answer from uphere.
– Yevgeniy AfanasyevNov 9 '15 at 22:45

Perfect answer for someone who want it to be working for input, select multiple and textarea. Because, using serialize you won't get all the items that are selected in the select tag. But, using .val() you'll get exactly what you want as an array. Simple, straight forward answer.
– Sailesh KothaNov 15 '17 at 3:10

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– Wahyu KristiantoJul 7 '16 at 14:55

But this link has a function for help his (I think). But I am going to put the code next time.
– Marcos CostaJul 7 '16 at 16:54