This post is already a year old ... but I really really like ES6 @dzuc's answer. However, it is incomplete because it cannot handle multiple selections or checkboxes. This has already been indicated, and code solutions have been proposed. I find them heavy and not optimized. Therefore, I wrote 2 versions based on @dzuc to handle these cases:
- For ASP-style forms where the name of several elements can simply be repeated.
let r=Array.from(fd).reduce( (o , [k,v]) => ( (!o[k]) ? {...o , [k] : v} : {...o , [k] : [...o[k] , v]} ) ,{} ); let obj=JSON.stringify(r);
Single line version of Hotshot:
Array.from(fd).reduce((o,[k,v])=>((!o[k])?{...o,[k]:v}:{...o,[k]:[...o[k],v]}),{});
- For forms in the style of PHP, where the names of several elements must have the suffix
[] .
let r=Array.from(fd).reduce( (o , [k,v]) => ( (k.split('[').length>1) ? (k=k.split('[')[0] , (!o[k]) ? {...o , [k] : [v]} : {...o , [k] : [...o[k] , v ]} ) : {...o , [k] : v} ) ,{} ); let obj=JSON.stringify(r);
Single line version of Hotshot:
Array.from(fd).reduce((o,[k,v])=>((k.split('[').length>1)?(k=k.split('[')[0],(!o[k])?{...o,[k]:[v]}:{...o,[k]:[...o[k],v]}):{...o,[k]:v}),{});
- An extension of a PHP form that supports multi-level arrays.
Since the last time I wrote the previous second case, at work there was a case when the PHP form has checkboxes at several levels. I wrote a new case to support the previous case and this one. I created a snippet to better demonstrate this case, show the result on the console for this demonstration, change it according to your needs. Trying to optimize it as best as possible without sacrificing performance, however, this degrades readability. The advantage is that arrays are objects, and variables that point to arrays are stored as references. You donβt need to be my guest.
let nosubmit = (e) => { e.preventDefault(); const f = Array.from(new FormData(e.target)); const obj = f.reduce((o, [k, v]) => { let a = v, b, i, m = k.split('['), n = m[0], l = m.length; if (l > 1) { a = b = o[n] || []; for (i = 1; i < l; i++) { m[i] = (m[i].split(']')[0] || b.length) * 1; b = b[m[i]] = ((i + 1) == l) ? v : b[m[i]] || []; } } return { ...o, [n]: a }; }, {}); console.log(obj); } document.querySelector('#theform').addEventListener('submit', nosubmit, {capture: true});
<h1>Multilevel Form</h1> <form action="#" method="POST" enctype="multipart/form-data" id="theform"> <input type="hidden" name="_id" value="93242" /> <input type="hidden" name="_fid" value="45c0ec96929bc0d39a904ab5c7af70ef" /> <label>Select: <select name="uselect"> <option value="A">A</option> <option value="B">B</option> <option value="C">C</option> </select> </label> <br /><br /> <label>Checkboxes one level:<br/> <input name="c1[]" type="checkbox" checked value="1"/>v1 <input name="c1[]" type="checkbox" checked value="2"/>v2 <input name="c1[]" type="checkbox" checked value="3"/>v3 </label> <br /><br /> <label>Checkboxes two levels:<br/> <input name="c2[0][]" type="checkbox" checked value="4"/>0 v4 <input name="c2[0][]" type="checkbox" checked value="5"/>0 v5 <input name="c2[0][]" type="checkbox" checked value="6"/>0 v6 <br/> <input name="c2[1][]" type="checkbox" checked value="7"/>1 v7 <input name="c2[1][]" type="checkbox" checked value="8"/>1 v8 <input name="c2[1][]" type="checkbox" checked value="9"/>1 v9 </label> <br /><br /> <label>Radios: <input type="radio" name="uradio" value="yes">YES <input type="radio" name="uradio" checked value="no">NO </label> <br /><br /> <input type="submit" value="Submit" /> </form>