How can I get form data with JavaScript/jQuery? - javascript

Is there a simple, one-line way to get the data of a form as it would be if it was to be submitted in the classic HTML-only way?
For example:
<form>
<input type="radio" name="foo" value="1" checked="checked" />
<input type="radio" name="foo" value="0" />
<input name="bar" value="xxx" />
<select name="this">
<option value="hi" selected="selected">Hi</option>
<option value="ho">Ho</option>
</form>
Output:
{
"foo": "1",
"bar": "xxx",
"this": "hi"
}
Something like this is too simple, since it does not (correctly) include textareas, selects, radio buttons and checkboxes:
$("#form input").each(function () {
data[theFieldName] = theFieldValue;
});

Use $('form').serializeArray(), which returns an array:
[
{"name":"foo","value":"1"},
{"name":"bar","value":"xxx"},
{"name":"this","value":"hi"}
]
Other option is $('form').serialize(), which returns a string:
"foo=1&bar=xxx&this=hi"
Take a look at this jsfiddle demo

$('form').serialize() //this produces: "foo=1&bar=xxx&this=hi"
demo

Updated answer for 2014: HTML5 FormData does this
var formData = new FormData(document.querySelector('form'))
You can then post formData exactly as it is - it contains all names and values used in the form.

Based on jQuery.serializeArray, returns key-value pairs.
var data = $('#form').serializeArray().reduce(function(obj, item) {
obj[item.name] = item.value;
return obj;
}, {});

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.

It is 2019 and there's a better way to do this:
const form = document.querySelector('form');
const data = new URLSearchParams(new FormData(form).entries());
or if you want a plain Object instead
const form = document.querySelector('form');
const data = Object.fromEntries(new FormData(form).entries());
although note that this won't work with duplicate keys like you get from multi-select and duplicate checkboxes with the same name.

Simplest way, 2022.
document.querySelector('form').addEventListener('submit', (e) => {
const data = Object.fromEntries(new FormData(e.target).entries());
console.log(data)
});
Output
{ name: 'Stackoverflow' }

use .serializeArray() to get the data in array format and then convert it into an object:
function getFormObj(formId) {
var formObj = {};
var inputs = $('#'+formId).serializeArray();
$.each(inputs, function (i, input) {
formObj[input.name] = input.value;
});
return formObj;
}

Here's a really simple and short soluton that even doesn't require Jquery.
var formElements=document.getElementById("myForm").elements;
var postData={};
for (var i=0; i<formElements.length; i++)
if (formElements[i].type!="submit")//we dont want to include the submit-buttom
postData[formElements[i].name]=formElements[i].value;

I use this:
jQuery Plugin
(function($){
$.fn.getFormData = function(){
var data = {};
var dataArray = $(this).serializeArray();
for(var i=0;i<dataArray.length;i++){
data[dataArray[i].name] = dataArray[i].value;
}
return data;
}
})(jQuery);
HTML Form
<form id='myform'>
<input name='myVar1' />
<input name='myVar2' />
</form>
Get the Data
var myData = $("#myForm").getFormData();

$("#form input, #form select, #form textarea").each(function() {
data[theFieldName] = theFieldValue;
});
other than that, you might want to look at serialize();

Here is a working JavaScript only implementation which correctly handles checkboxes, radio buttons, and sliders (probably other input types as well, but I've only tested these).
function setOrPush(target, val) {
var result = val;
if (target) {
result = [target];
result.push(val);
}
return result;
}
function getFormResults(formElement) {
var formElements = formElement.elements;
var formParams = {};
var i = 0;
var elem = null;
for (i = 0; i < formElements.length; i += 1) {
elem = formElements[i];
switch (elem.type) {
case 'submit':
break;
case 'radio':
if (elem.checked) {
formParams[elem.name] = elem.value;
}
break;
case 'checkbox':
if (elem.checked) {
formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
}
break;
default:
formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
}
}
return formParams;
}
Working example:
function setOrPush(target, val) {
var result = val;
if (target) {
result = [target];
result.push(val);
}
return result;
}
function getFormResults(formElement) {
var formElements = formElement.elements;
var formParams = {};
var i = 0;
var elem = null;
for (i = 0; i < formElements.length; i += 1) {
elem = formElements[i];
switch (elem.type) {
case 'submit':
break;
case 'radio':
if (elem.checked) {
formParams[elem.name] = elem.value;
}
break;
case 'checkbox':
if (elem.checked) {
formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
}
break;
default:
formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
}
}
return formParams;
}
//
// Boilerplate for running the snippet/form
//
function ok() {
var params = getFormResults(document.getElementById('main_form'));
document.getElementById('results_wrapper').innerHTML = JSON.stringify(params, null, ' ');
}
(function() {
var main_form = document.getElementById('main_form');
main_form.addEventListener('submit', function(event) {
event.preventDefault();
ok();
}, false);
})();
<form id="main_form">
<div id="questions_wrapper">
<p>what is a?</p>
<div>
<input type="radio" required="" name="q_0" value="a" id="a_0">
<label for="a_0">a</label>
<input type="radio" required="" name="q_0" value="b" id="a_1">
<label for="a_1">b</label>
<input type="radio" required="" name="q_0" value="c" id="a_2">
<label for="a_2">c</label>
<input type="radio" required="" name="q_0" value="d" id="a_3">
<label for="a_3">d</label>
</div>
<div class="question range">
<label for="a_13">A?</label>
<input type="range" required="" name="q_3" id="a_13" min="0" max="10" step="1" list="q_3_dl">
<datalist id="q_3_dl">
<option value="0"></option>
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
<option value="4"></option>
<option value="5"></option>
<option value="6"></option>
<option value="7"></option>
<option value="8"></option>
<option value="9"></option>
<option value="10"></option>
</datalist>
</div>
<p>A and/or B?</p>
<div>
<input type="checkbox" name="q_4" value="A" id="a_14">
<label for="a_14">A</label>
<input type="checkbox" name="q_4" value="B" id="a_15">
<label for="a_15">B</label>
</div>
</div>
<button id="btn" type="submit">OK</button>
</form>
<div id="results_wrapper"></div>
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.

I have included the answer to also give back the object required.
function getFormData(form) {
var rawJson = form.serializeArray();
var model = {};
$.map(rawJson, function (n, i) {
model[n['name']] = n['value'];
});
return model;
}

Based on neuront's response I created a simple JQuery method that gets the form data in key-value pairs but it works for multi-selects and for array inputs with name='example[]'.
This is how it is used:
var form_data = $("#form").getFormObject();
You can find an example below of its definition and how it works.
// Function start
$.fn.getFormObject = function() {
var object = $(this).serializeArray().reduce(function(obj, item) {
var name = item.name.replace("[]", "");
if ( typeof obj[name] !== "undefined" ) {
if ( !Array.isArray(obj[name]) ) {
obj[name] = [ obj[name], item.value ];
} else {
obj[name].push(item.value);
}
} else {
obj[name] = item.value;
}
return obj;
}, {});
return object;
}
// Function ends
// This is how it's used
$("#getObject").click( function() {
var form_data = $("#form").getFormObject();
console.log(form_data);
});
/* Only to make view better ;) */
#getObject {
padding: 10px;
cursor:pointer;
background:#0098EE;
color:white;
display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form id="form">
<input type="text" name="text" value="Hola amigo" />
<input type="text" name="text_array[]" value="Array 1" />
<input type="text" name="text_array[]" value="Array 2" />
<input type="text" name="text_array[]" value="Array 3" />
<select name="multiselect" multiple>
<option name="option1" selected> option 1 </option>
<option name="option2" selected> option 2 </option>
</select>
<input type="checkbox" name="checkbox" value="checkbox1" checked/>
<input type="checkbox" name="checkbox" value="checkbox2" checked/>
<input type="radio" name="radio" value="radio1" checked/>
<input type="radio" name="radio" value="radio2"/>
</form>
<div id="getObject"> Get object (check the console!) </div>

If you are using jQuery, here is a little function that will do what you are looking for.
First, add an ID to your form (unless it is the only form on the page, then you can just use 'form' as the dom query)
<form id="some-form">
<input type="radio" name="foo" value="1" checked="checked" />
<input type="radio" name="foo" value="0" />
<input name="bar" value="xxx" />
<select name="this">
<option value="hi" selected="selected">Hi</option>
<option value="ho">Ho</option>
</form>
<script>
//read in a form's data and convert it to a key:value object
function getFormData(dom_query){
var out = {};
var s_data = $(dom_query).serializeArray();
//transform into simple data/value object
for(var i = 0; i<s_data.length; i++){
var record = s_data[i];
out[record.name] = record.value;
}
return out;
}
console.log(getFormData('#some-form'));
</script>
The output would look like:
{
"foo": "1",
"bar": "xxx",
"this": "hi"
}

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.
var formElement = document.getElementById("myform_id");
var formData = new FormData(formElement);
console.log(formData);

This will append all form fields to the JavaScript object "res":
var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
res[obj.name] = $(obj).val();
})

var formData = new FormData($('#form-id'));
params = $('#form-id').serializeArray();
$.each(params, function(i, val) {
formData.append(val.name, val.value);
});

For those of you who would prefer an Object as opposed to a serialized string (like the one returned by $(form).serialize(), and a slight improvement on $(form).serializeArray()), feel free to use the code below:
var Form = {
_form: null,
_validate: function(){
if(!this._form || this._form.tagName.toLowerCase() !== "form") return false;
if(!this._form.elements.length) return false;
return true;
}, _loopFields: function(callback){
var elements = this._form.elements;
for(var i = 0; i < elements.length; i++){
var element = form.elements[i];
if(name !== ""){
callback(this._valueOfField(element));
}
}
}, _valueOfField: function(element){
var type = element.type;
var name = element.name.trim();
var nodeName = element.nodeName.toLowerCase();
switch(nodeName){
case "input":
if(type === "radio" || type === "checkbox"){
if(element.checked){
return element.value;
}
}
return element.value;
break;
case "select":
if(type === "select-multiple"){
for(var i = 0; i < element.options.length; i++){
if(options[i].selected){
return element.value;
}
}
}
return element.value;
break;
case "button":
switch(type){
case "reset":
case "submit":
case "button":
return element.value;
break;
}
break;
}
}, serialize: function(form){
var data = {};
this._form = form;
if(this._validate()){
this._loopFields(function(value){
if(value !== null) data[name] = value;
});
}
return data;
}
};
To execute it, just use Form.serialize(form) and the function will return an Object similar to this:
<!-- { username: "username", password: "password" } !-->
<input type="text" value="username">
<input type="password" value="password">
As a bonus, it means you don't have to install the entire bundle of jQuery just for one serialize function.

I'm kind of supprised because no one mentioned below solution.
Get form data via document.forms.namedItem function
var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function(ev) {
var oData = new FormData(form);
}
The HT
<form name="fileinfo">
<label>Your email address:</label>
<input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
<label>Custom file label:</label>
<input type="text" name="filelabel" size="12" maxlength="32" /><br />
<label>File to stash:</label>
<input type="file" name="file" required />
<input type="submit" value="Stash the file!" />
</form>
<div></div>

I wrote a library to solve this very problem: JSONForms. It takes a form, goes through each input and builds a JSON object you can easily read.
Say you have the following form:
<form enctype='application/json'>
<input name='places[0][city]' value='New York City'>
<input type='number' name='places[0][population]' value='8175133'>
<input name='places[1][city]' value='Los Angeles'>
<input type='number' name='places[1][population]' value='3792621'>
<input name='places[2][city]' value='Chicago'>
<input type='number' name='places[2][population]' value='2695598'>
</form>
Passing the form to JSONForms' encode method returns you the following object:
{
"places": [
{
"city": "New York City",
"population": 8175133
},
{
"city": "Los Angeles",
"population": 3792621
},
{
"city": "Chicago",
"population": 2695598
}
]
}
Here's demo with your form.

function getFormData($form){
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function(n, i){
if(indexed_array[n['name']] == undefined){
indexed_array[n['name']] = [n['value']];
}else{
indexed_array[n['name']].push(n['value']);
}
});
return indexed_array;
}

you can use this function for have an object or a JSON from form.
for use it:
var object = formService.getObjectFormFields("#idform");
function getObjectFormFields(formSelector)
{
/// <summary>Função que retorna objeto com base nas propriedades name dos elementos do formulário.</summary>
/// <param name="formSelector" type="String">Seletor do formulário</param>
var form = $(formSelector);
var result = {};
var arrayAuxiliar = [];
form.find(":input:text").each(function (index, element)
{
var name = $(element).attr('name');
var value = $(element).val();
result[name] = value;
});
form.find(":input[type=hidden]").each(function (index, element)
{
var name = $(element).attr('name');
var value = $(element).val();
result[name] = value;
});
form.find(":input:checked").each(function (index, element)
{
var name;
var value;
if ($(this).attr("type") == "radio")
{
name = $(element).attr('name');
value = $(element).val();
result[name] = value;
}
else if ($(this).attr("type") == "checkbox")
{
name = $(element).attr('name');
value = $(element).val();
if (result[name])
{
if (Array.isArray(result[name]))
{
result[name].push(value);
} else
{
var aux = result[name];
result[name] = [];
result[name].push(aux);
result[name].push(value);
}
} else
{
result[name] = [];
result[name].push(value);
}
}
});
form.find("select option:selected").each(function (index, element)
{
var name = $(element).parent().attr('name');
var value = $(element).val();
result[name] = value;
});
arrayAuxiliar = [];
form.find("checkbox:checked").each(function (index, element)
{
var name = $(element).attr('name');
var value = $(element).val();
result[name] = arrayAuxiliar.push(value);
});
form.find("textarea").each(function (index, element)
{
var name = $(element).attr('name');
var value = $(element).val();
result[name] = value;
});
return result;
}

$( "form" ).bind( "submit", function(e) {
e.preventDefault();
console.log( $(this).serializeObject() );
//console.log( $(this).serialize() );
//console.log( $(this).serializeArray() );
});
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each( a, function() {
if ( o[this.name] !== undefined)
{
if ( ! o[this.name].push )
{
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
}
else
{
o[this.name] = this.value || '';
}
});
return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<form>
<input type="radio" name="foo" value="1" checked="checked" />
<input type="radio" name="foo" value="0" />
<input name="bar" value="xxx" />
<select name="this">
<option value="hi" selected="selected">Hi</option>
<option value="ho">Ho</option>
</select>
<input type="submit" value="Submit" />
</form>
Codepen

I wrote a function that takes care of multiple checkboxes and multiple selects. In those cases it returns an array.
function getFormData(formId) {
return $('#' + formId).serializeArray().reduce(function (obj, item) {
var name = item.name,
value = item.value;
if (obj.hasOwnProperty(name)) {
if (typeof obj[name] == "string") {
obj[name] = [obj[name]];
obj[name].push(value);
} else {
obj[name].push(value);
}
} else {
obj[name] = value;
}
return obj;
}, {});
}

Here is a nice vanilla JS function I wrote to extract form data as an object. It also has options for inserting additions into the object, and for clearing the form input fields.
const extractFormData = ({ form, clear, add }) => {
return [].slice.call(form.children).filter(node => node.nodeName === 'INPUT')
.reduce((formData, input) => {
const value = input.value
if (clear) { input.value = '' }
return {
...formData,
[input.name]: value
}
}, add)
}
Here is an example of its use with a post request:
submitGrudge(e) {
e.preventDefault()
const form = e.target
const add = { id: Date.now(), forgiven: false }
const grudge = extractFormData({ form, add, clear: true })
// grudge = {
// "name": "Example name",
// "offense": "Example string",
// "date": "2017-02-16",
// "id": 1487877281983,
// "forgiven": false
// }
fetch('http://localhost:3001/api/grudge', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(grudge)
})
.then(response => response.json())
.then(grudges => this.setState({ grudges }))
.catch(err => console.log('error: ', err))
}

showing form input element fields and input file to submit your form without page refresh and grab all values with file include in it here it is
<form id="imageUploadForm" action="" method="post" enctype="multipart/form-data">
<input type="text" class="form-control" id="fname" name='fname' placeholder="First Name" >
<input type="text" class="form-control" name='lname' id="lname" placeholder="Last Name">
<input type="number" name='phoneno' class="form-control" id="phoneno" placeholder="Phone Number">
<textarea class="form-control" name='address' id="address" rows="5" cols="5" placeholder="Your Address"></textarea>
<input type="file" name="file" id="file" >
<input type="submit" id="sub" value="Registration">
</form>
on Submit button page will send ajax request to your php file.
$('#imageUploadForm').on('submit',(function(e)
{
fname = $('#fname').val();
lname = $('#lname').val();
address = $('#address').val();
phoneno = $('#phoneno').val();
file = $('#file').val();
e.preventDefault();
var formData = new FormData(this);
formData.append('file', $('#file')[0]);
formData.append('fname',$('#fname').val());
formData.append('lname',$('#lname').val());
formData.append('phoneno',$('#phoneno').val());
formData.append('address',$('#address').val());
$.ajax({
type:'POST',
url: "test.php",
//url: '<?php echo base_url().'edit_profile/edit_profile2';?>',
data:formData,
cache:false,
contentType: false,
processData: false,
success:function(data)
{
alert('Data with file are submitted !');
}
});
}))

$(form).serializeArray().reduce(function (obj, item) {
if (obj[item.name]) {
if ($.isArray(obj[item.name])) {
obj[item.name].push(item.value);
} else {
var previousValue = obj[item.name];
obj[item.name] = [previousValue, item.value];
}
} else {
obj[item.name] = item.value;
}
return obj;
}, {});
It will fix issue:couldn't work with multiselects.

Here's my version in vanilla JS (tested on Chrome)
works with:
name="input"
name="form[name]" (creates an object)
name="checkbox[]" (creates an object with an array)
name="form[checkbox][]" (creates an array)
name="form[select][name]" (creates an object with an object containing only the selected value)
/**
* Get the values from a form
* #param formId ( ID without the # )
* #returns {object}
*/
function getFormValues( formId )
{
let postData = {};
let form = document.forms[formId];
let formData = new FormData( form );
for ( const value of formData.entries() )
{
let container = postData;
let key = value[0];
let arrayKeys = key.match( /\[[\w\-]*\]/g ); // Check for any arrays
if ( arrayKeys !== null )
{
arrayKeys.unshift( key.substr( 0, key.search( /\[/ ) ) ); // prepend the first key to the list
for ( let i = 0, count = arrayKeys.length, lastRun = count - 1; i < count; i++ )
{
let _key = arrayKeys[i];
_key = _key.replace( "[", '' ).replace( "]", '' ); // Remove the brackets []
if ( _key === '' )
{
if ( ! Array.isArray( container ) )
{
container = [];
}
_key = container.length;
}
if ( ! (_key in container) ) // Create an object for the key if it doesn't exist
{
if ( i !== lastRun && arrayKeys[i + 1] === '[]' )
{
container[_key] = [];
}
else
{
container[_key] = {};
}
}
if ( i !== lastRun ) // Until we're the last item, swap container with it's child
{
container = container[_key];
}
key = _key;
}
}
container[key] = value[1]; // finally assign the value
}
return postData;
}

You are all not fully correct. You cannot write:
formObj[input.name] = input.value;
Because this way if you have multiselect list - its values will be overwritten with the last one, since it's transmitted as: "param1" : "value1", "param1" : "value2".
So, correct approach is:
if (formData[input.name] === undefined) {
formData[input.name] = input.value;
}
else {
var inputFieldArray = $.merge([], $.isArray(formData[input.name]) ? formData[input.name] : [formData[input.name]]);
$.merge(inputFieldArray, [input.value]);
formData[input.name] = $.merge([], inputFieldArray);
}

Related

Serialize form and change input names (remove the array part of the input names)

I want to serialize my html form and submit it to my sever via ajax, but before submitting the form, I want to rename the variable names and remove the initiali part, which is: BranchViewModels[0]. for example, I want to change:
change: BranchViewModels[0].BranchName to: BranchName
change: BranchViewModels[1].AddressViewModel.AddressId to : AddressViewModel.AddressId
Basically when I generate form, all the input names are rendered as an array, but before submitting the form, I want to get rid of array section of the input name (BranchViewModels[0]. in this example).
I have explained why I am doing this here
I have also created a jsfiddle for the following example.
function updateBranch() {
$('.save-branch-button').click(function() {
var branchForm = $(this).closest('form');
var serializedform = branchForm.find('.form :input').serialize();
alert('I want to change the input names in this serialized form: \n\n' + serializedform );
// 1. iterated through serialized form
//
// remove BranchViewModels[i]. from the name, e.g.
// replace: BranchViewModels[0].BranchName
// with: BranchName
// 2. Submit the form
/* $.ajax({
url: "/my-server",
data: {branchViewModel: <-- serialized model},
dataType: 'json',
type: "POST"}); */
});
}
jQuery(document).ready(function($) {
updateBranch();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form onsubmit="return false;" novalidate="novalidate">
<div class="form">
<div class="form-group">
<label>Branch name</label>
<input class="form-control" data-val="true" id="BranchViewModels_0__BranchName" name="BranchViewModels[0].BranchName" type="text" value="branch 1">
</div>
<hr />
<div class="form-group">
<label>Branch location</label>
<div>
<input data-val="true" id="BranchViewModels_0__AddressViewModel_AddressId" name="BranchViewModels[0].AddressViewModel.AddressId" value="1956">
</div>
<div>
<input class="address-street-address" data-val="true" id="BranchViewModels_0__AddressViewModel_StreetAddress" name="BranchViewModels[0].AddressViewModel.StreetAddress" value="Wellington 6011, New Zealand">
</div>
</div>
<input type="button" class="btn btn-primary-action save-branch-button" value="Save">
</div>
</form>
function updateBranch() {
$('.save-branch-button').click(function() {
var branchForm = $(this).closest('form');
var serializedform = branchForm.find('.form :input').serializeArray();
console.log(serializedform);
const obj = {};
for(let d of serializedform){
obj[d.name.split('.').pop()] = d.value
}
console.log(obj);
}
Return serialize data to Deserialize then change to you want anything Hope this help you.
console.log(deparam(serializedform));
function deparam(query) {
var pairs, i, keyValuePair, key, value, map = {};
// remove leading question mark if its there
if (query.slice(0, 1) === '?') {
query = query.slice(1);
}
if (query !== '') {
pairs = query.split('&');
for (i = 0; i < pairs.length; i += 1) {
keyValuePair = pairs[i].split('=');
key = decodeURIComponent(keyValuePair[0]);
value = (keyValuePair.length > 1) ? decodeURIComponent(keyValuePair[1]) : undefined;
map[key] = value;
}
}
return map;
}

How to get a key/value data set from a HTML form

I'm simply looking for a way to get all the values from a <form>.
I searched the Web for a while, stumbling across FormData, which seems quite what I'm looking for.
However its API is not available on any browser, so I need an alternative.
What I need in my specific case is an object of key/value pairs. For example:
<form>
<input type="text" name="firstname" value="John" />
<input type="text" name="surname" value="doe" />
<input type="email" name="email" value="" />
<input type="radio" name="gender" value="male" />
<input type="radio" name="gender" value="female" />
</form>
The object should be:
{
firstname: "John",
surname: "doe",
email: "",
gender: ""
}
Edit: The above is just an example, it should work not only with <input> but also with the other tags (e.g. <select>, <textarea> and so on... even <input type="file"> should be supported).
When I originally wrote this answer FormData was not widely supported (and this was called out explicitly in the question). Now that it's been 6 years, FormData has excellent cross-browser support.
Because of this, I highly recommend using FormData directly to access data or serialize data to the server.
Jake Archibald has an excellent post describing FormData (and URLSearchParams) in depth, which I won't attempt to reproduce here, however I will include a few snippets that are relevant:
You can populate FormData state directly:
const formData = new FormData();
formData.set('foo', 'bar');
formData.set('hello', 'world');
...you can read an HTML form directly as FormData:
const formElement = document.querySelector('form');
const formData = new FormData(formElement);
console.log(formData.get('username'));
...you can use FormData directly as a fetch body:
const formData = new FormData();
formData.set('foo', 'bar');
formData.set('hello', 'world');
fetch(url, {
method: 'POST',
body: formData,
});
I recommend reading Jake's post in full and using the APIs that come with the browser over adding more code to build a less-resilient version of the same thing.
My original post preserved for posterity's sake:
Without a strong definition of what should happen with edge cases, and what level of browser support is required, it's difficult to give a single perfect answer to the question.
There are a lot of form behaviors that are easy to miss, which is why I recommend using a well-maintained function from a library, such as jQuery's serializeArray():
$('form').serializeArray();
I understand that there's a big push recently to move away from needlessly including jQuery, so for those who are interested in a vanilla JS solution serializeArray just won't do.
The next difficulty comes from determining what level of browser support is required. HTMLFormElement.elements significantly simplifies a serialization implementation, and selecting the form-associated elements without it is quite a pain.
Consider:
<form id="example">...</form>
<input type="text" form="example" name="lorem" value="ipsum"/>
A conforming implementation needs to include the input element. I will assume that I can use it, and leave polyfilling it as an exercise to the reader.
After that it'd unclear how <input type="file"/> should be supported. I'm not keen on needlessly serializing file elements into a string, so I've made the assumption that the serialization will be of the input's name and value, even though the value is practically useless.
Lastly, an input structure of:
{
'input name': 'value',
'textarea name': 'value'
}
Is excessively naive as it doesn't account for <select multiple> elements, or cases where two inputs have the same name. I've made the assumption that the input would be better as:
[
{
name: 'input name',
value: 'value'
},
{
name: 'textarea name',
value: 'value'
}
]
...and again leave transforming this into a different structure as an exercise for the reader.
Give me teh codez already!
var serialize = (function (slice) {
return function (form) {
//no form, no serialization
if (form == null)
return null;
//get the form elements and convert to an array
return slice.call(form.elements)
.filter(function (element) {
//remove disabled elements
return !element.disabled;
}).filter(function (element) {
//remove unchecked checkboxes and radio buttons
return !/^input$/i.test(element.tagName) || !/^(?:checkbox|radio)$/i.test(element.type) || element.checked;
}).filter(function (element) {
//remove <select multiple> elements with no values selected
return !/^select$/i.test(element.tagName) || element.selectedOptions.length > 0;
}).map(function (element) {
switch (element.tagName.toLowerCase()) {
case 'checkbox':
case 'radio':
return {
name: element.name,
value: element.value === null ? 'on' : element.value
};
case 'select':
if (element.multiple) {
return {
name: element.name,
value: slice.call(element.selectedOptions)
.map(function (option) {
return option.value;
})
};
}
return {
name: element.name,
value: element.value
};
default:
return {
name: element.name,
value: element.value || ''
};
}
});
}
}(Array.prototype.slice));
You could go for a manual way (Below code is not tested though);
var form = document.getElementsByTagName("form");
var inputs = form[0].getElementsByTagName("input");
var formData = {};
for(var i=0; i< inputs.length; i++){
formData[inputs[i].name] = inputs[i].value;
}
var formdata = JSON.stringify(formData);
if you use a library this would be easier.
Eg:- in jQuery:
var formObjects = $("form :input");
formObjects.each(
function(){
formData[$(this).attr("name")] = $(this).val(); /*setting up name/value pairs */
}
);
in this code formObjects contains all input, select and textarea and other form element tags. so we don't need to manually search for each like in plain JS. Except for radio buttons (As #enhzflep implied this doesn't work correct for input[type=radio] )
But if you use jQuery you can directly use jQuery's serialize() function to grab the whole form by name-value pairs.
var url_friendly_name_value_string = $("form").serialize();
If you need object of {key: value, ...}
const form = document.getElementById("your-form")
const formEntries = new FormData(form).entries();
const formData = Object.assign(...Array.from(formEntries, ([name, value]) => ({[name]: value})));
console.log(formData)
You would need to manually generate the json/javascript object before sending it to the server.
Should be a method called onSubmit which would pick each of the form's input value and create an object which can then be sent to the server page.
You can refer this answer which is similar to what you are looking for:
Convert form data to JavaScript object with jQuery
Just use jQuery.
HTML:
<form id="my-form">
<input type="text" name="my-field" />
</form>
JS:
var data = $('form#my-form').serializeArray(); // [{'my-field': 'value'}]
$.ajax({
data: data
//other config goes here
});
Pardon my haste for not formatting the example, But its good to understand. Click 'Get All Values' to see the key/value pair in alert.
JS Fiddle
$(function(){
$(".getFormVal").on("click",function(e){
e.preventDefault();
var formObj={};
var formEle = $(".form").find("input:not([type=submit],[type=button]),select,textarea");
$(formEle).each(function(){
if($(this).prop("tagName").toLowerCase() == "input"){
if( ($(this).attr("type").toLowerCase() == "text") ||
($(this).attr("type").toLowerCase() == "radio" && $(this).is(":checked")) ||
($(this).attr("type").toLowerCase() == "file") ){
formObj[$(this).attr("name")] = $(this).val();
}else if( $(this).attr("type").toLowerCase() == "checkbox" && $(this).is(":checked") ){
if(formObj[$(this).attr("name")] === undefined){
formObj[$(this).attr("name")] = [];
}
formObj[$(this).attr("name")].push($(this).val());
}
}else if( $(this).prop("tagName").toLowerCase() == "textarea" ){
formObj[$(this).attr("name")] = $(this).val();
}else if( $(this).prop("tagName").toLowerCase() == "select" ){
if($(this).attr("multiple")){
if(formObj[$(this).attr("name")] === undefined){
var selectEleName = $(this).attr("name");
formObj[selectEleName] = [];
}
$('option:selected',this).each(function(i, selected){
formObj[selectEleName].push($(this).attr("value"));
});
}else{
formObj[$(this).attr("name")] = $(this).val();
}
}
});
alert(JSON.stringify(formObj));
});
});
I'm suggesting you to use css selectors for selecting the inputs from your form: querySelector and querySelectorAll.
Here's the working code and here's the js code.
function get_form_data()
{
var el = document.querySelector('form');
var matches = el.querySelectorAll('input[name]');
var data = {};
for(var i=0; i< matches.length; i++){
data[matches[i].name] = matches[i].value;
}
var json_data = JSON.stringify(data);
}
Sure you can modify the selectors for your needs.
I hope this will be useful and good luck to you.
Here is the pure javascript solution which gives the required output for all kind of inputs in a form including files.
Sample output
{
"firstname":"John",
"surname":"doe",
"email":"abc#gmail.com",
"gender":"female",
"subscribe":true,
"selection":"M",
"description":"sdfs sdfs sdf",
"upload":"data:text/plain;base64,/v8JLAk+CTMAIAkVCUcJNgk1ACAJIAk+CRUJMAlHAC4ADQAKAA0ACgk5CT8JAgkoCU0JJglBCSQJTQk1CT4JGgk+ACAJHwkjCSQJTQkVCT4JMAAuACAJNQlNCS8JAgkXCRoJPwkkCU0JMAkVCT4JMAAgCSQJRwAgCTkJPwkoCU0JJglBCTkJTQkwCUEJJgkvCTgJLglNCTAJPgkfAA0ACgkkCUsJAgkhACAJNQk+CRwJNQlBCSgAIAkoCU0JLwk+CS8AIAkuCT8JMwkkACAJKAk4CUcJMgAgCSQJMAANAAoJJAlLCQIJIQk+CSQAIAk1CT4JHAk1CUEJKAAgCSgJTQkvCT4JLwAgCS4JPwkzCTUJPgAsAA0ACgkqCSMAIAkoCU0JLwk+CS8AIAk5CT4AIAkdCT4JMgk+CRoAIAkqCT4JOQk/CRwJRwAuAA0ACgkPCRUAIAkuCT4JIwlBCTgAIAkkCUEJLgkaCU0JLwk+ACAJLgk+CR0JTQkvCT4AIAk4CT4JMAkWCT4JGgAsACAJCQkCCRoJQAkoCUcAIAkGCSMJPwAgCTUJHAkoCT4JKAlHACAJLgk+CSQJTQkwACAJFQkuCUAJGgAuACAJKgk+CTkJJAAgCTkJSwkkCT4AIAkGCSoJMglNCS8JPgAgCQYJHAlBCSwJPgkcCUEJGglAACAJKgkwCT8JOAlNCSUJPwkkCUAALgAgCTkJSwkjCT4JMAk+ACAJLgkwCT4JIAlAACAJLgk+CSMJOAk+CTUJMAkaCT4AIAkFCSgJTQkvCT4JLwAsACAJJAlLCTkJPwAgCS4JOQk+CTAJPgk3CU0JHwlNCTAJPgkkCRoALgAgCS4JQgkXACAJFwk/CTMJQQkoACAJFwkqCU0JKgAgCSwJOAkyCUcJMglHACAJOAkwCRUJPgkwAC4AIAkkCUAAIAkaCT4JMAlAACAJLAk+CRwJQQkoCUcAIAk5CUsJIwk+CTAJQAAgCRcJMwkaCUcJKglAAC4AIAkGCSQJPgAgCRUJPgkvACAJFQkwCT4JNQlHAC4ALgkGCSoJIwAgCTkJPwAgCRcJKglNCSoAIAksCTgJPgk1CUcAIAkVCT8AIAkGCTUJPgkcACAJCQkaCTIJPgk1CT4ALgAgCSQJSwAgCS4JPgkjCUEJOAAgCTgJPgkuCT4JKAlNCS8AIAkoCTUJTQk5CSQJPgAgCSQJTQkvCT4JKAlHACAJNgk+CQIJJAAgCSwJOAkjCUcAIAk5CT4AIAk1CT8JGgk+CTAAIAkVCScJQAkaACAJFQlHCTIJPgAgCSgJPgk5CT8AIAkGCSMJPwAgCSsJPAlBCQIJFQkyCUAAIAkkCUEJJAk+CTAJPwAgCS4JMAk+CSAJPwAgCQUJOAlNCS4JPwkkCUcJOAk+CSAJQAAgCRUJPgkwCSMAIAkkCUsAIAk5CUsJJAk+ACAJLAk+CTMAIAkgCT4JFQkwCUcALgANAAoJLAk+CTMJKAlHACAJBgkqCTIJPgAgCSQJSwkrCTwJFgk+CSgJPgAgCQkJGAkhCTIJPgAuACAJLAkYCSQJPgAgCSwJGAkkCT4AIAkuCT4JNQkzCUcAIAkcCS4JQQAgCTIJPgkXCTIJRwAsACAJJAk+CRUJJgAgCTUJPgkiCUEAIAkyCT4JFwkyCUAALgAgCSoJIwAgCSgJFQlNCRUJPwAgCRUJMAlBACAJFQk+CS8AIAk5CT4AIAkqCU0JMAk2CU0JKAAgCTkJSwkkCT4JGgAuACAJBwklCUcJGgAgCTUJIQk/CTIJPgkCCSgJQAAgCSoJTQkwCSwJSwknCSgJFQk+CTAAIAkgCT4JFQkwCUcJAgkoCUAAIAkqCU0JMAk2CU0JKAAgCTUJPwkaCT4JMAkyCT4ALgAuAA0ACiAcCSwJPgkzACAJMglLCRUJRwAgCSQJMAAgCRwJLgkyCUAAIAkqCSMAIAkvCT4JMgk+ACAJOAkCCRgJHwkoCUcJGglHACAJMAlBCSoAIAkmCUcJIwk+CTAAIAkVCT8AIAkoCT4JOQlAAD8AIAkVCT4JOQk/ACAJKAk+CTUAIAk4CUEJGgkkCS8AIAkVCT4AIAk4CQIJGAkfCSgJRwAgCTgJPgkgCUAAPyAdAA0ACgksCT4JMwAgCQkJJAlNCSQJMAkyCT4ALgAuIB0JNQk/CRoJPgkwACAJJAkwACAJGgk+CTIJQQAgCQYJOQlHAC4ALgkqCSMAIAk4CQIJGAkfCSgJRwkyCT4AIAkoCT4JNSAmIB0ADQAKIBwJLgk/ACAJOAk+CQIJFwkkCUsAIAkoCT4JNSAmAC4ALgk2CT8JNQk4CUcJKAk+IB0ADQAKCWcJbwAgCRwJQQkoACAJZwlvCWwJbAAuAC4JNgk/CTUJPgkcCUAAIAkqCT4JMAlNCRUALgAuCTkJHAk+CTAJSwkCCSgJPwAgCRwJLgkyCUcJMgk+ACAJLgkwCT4JIAlAACAJLgk+CSMJQQk4AC4AIAkGCSMJPwAgCTgJTQklCT4JKgkoACAJHQk+CTIJQAAgCTYJPwk1CTgJRwkoCT4ALgAgCRcJMAlNCSYJQAAgCQYJIwk/ACAJIAk+CRUJMAlHACAJOQlHACAJBwklCUcAIAkcCUEJMwkyCUcJMglHACAJFwkjCT8JJAAgCQYJHAkkCT4JFwk+CS8JFQAgCSsJPAk/CTgJFQkfCTIJRwkyCUcAIAkoCT4JOQk/CS8JRwAuAA0ACgkoCTUJTQk1CSYJPwkaCT4AIAkVCT4JMwAsACAJMAk+CTcJTQkfCU0JMAk/CS8AIAkoCUcJJAlNCS8JPgkCCSgJQAAgCS8JPgkkCU0JMAk+ACAJBgkvCUsJHAk/CSQAIAkVCUcJMglNCS8JPgAgCTkJSwkkCU0JLwk+AC4AIAk5CT8JKAlNCSYJQQkkCU0JNQk+CRoJPgAgCQYJNQk+CRwAIAksCUEJMgkCCSYAIAk5CUsJJAAgCTkJSwkkCT4ALgAgCQ8JFQkaACAJMgkVCU0JNwlNCS8AICAcCTAJPgkuACAJLgkCCSYJPwkwIB0ALgAgCTYJPwk1CTgJRwkoCUcJKAlHCTkJPwAgCTkJPwkCCSYJQgkkCU0JNQk+CRoJPgAgCQUJAgkXCT4JMAAgCTkJPgkkCT4JJAAgCRgJRwkkCTIJRwkyCT4ALgAgCTYJRwk1CR8JPwAgCSQJRwAgCR0JPgkyCUcJGgAuACAJLAk+CSwJMAlAACAJLgk4CU0JHAk/CSYAIAkGCSEJNQlAACAJFQlHCTIJQAAgCRcJRwkyCUAALgAgCSQJTQkvCT4AIAkoCQIJJAkwACAJCQk4CTMJMgk+ACAJJAlLACAJDwkVCRoAIAkmCQIJFwk+AC4AIAkuCT8AIAkuCT8AIAkuCU0JOQkjCSMJPgkwCUcAIAkGCSMJPwAgCTgJTQk1CSQJAwkyCT4AIAk5CT8JAgkmCUIJGglHACAJKAlHCSQJRwAgCS4JTQk5CSMJNQlBCSgAIAkYCUcJIwk+CTAJTQkvCT4JAgkaCUcAIAk5CT8AIAkqCTAJPwk4CU0JJQk/CSQJQAAgCSwJGAlBCSgAIAknCT4JLAlHACAJJgkjCT4JIwkyCUcALgAgCSQJTQkvCT4JKAlAACAJOAkwCTMJOAlLCR8AIAkcCTUJPgksCSYJPgkwCUAAIAkoCT4JFQk+CTAJMglAAC4AIAkvCT4JJAAgCQYJLglNCTkJPwAgCSgJNQlNCTkJJAlLAC4AIAkvCT4JJAAgCQYJLgkaCT4AIAkPCRUJOQlAACAJLgk+CSMJQQk4ACAJKAk1CU0JOQkkCT4AIAkFCTgJJAlACTIAIAkkCTAAIAkkCUcAIAkFCTgJJAlACTIAICAcCTYJPwk1CTgJSAkoCT8JFSAcAC4AIAkkCU0JLwk+ACAJNQlHCTMJPwAgCSwJPgkzCT4JOAk+CTkJRwksCT4JAgkoCT4AIAk1CT8JGgk+CTAJMglHACAJFwlHCTIJRwAuAC4ADQAKIBwJFQk+CS8AIAk5CUcAIAkkCUEJLgkaCUcAIAk2CT8JNQk4CUgJKAk/CRUAIAk5CUsJJAlHAD8gHQANAAoJLwk+ACAJNQlHCTMJPwAgCSwJPgkzCT4JOAk+CTkJRwksACAJOAk5CRwAIAkuCU0JOQkjCUEJKAAgCRcJRwkyCUcAIAkFCTgJJAlHACAJFQk/ACAJOQlHACAJBgkuCRoJRwAgCRUJSwkjCRoAIAkoCTUJTQk5CUcJJCAmAA0ACgkqCSMAIAkbCUcALgAuACAJNgk/CTUJOAlICSgJPwkVCT4JAgkoCT4AIAkPCRUJHwlHACAJHwk+CRUJQQkoACAJJglHCSMJPgkwCT4AIAk5CT4AIAkoCUcJJAk+CRoAIAkoCTUJTQk5CUcALgAgCSQJTQkvCT4JKAlHACAJOAkCCSoJQQkwCU0JIwkqCSMJRwAgCTYJPwk1CTgJSAkoCT8JFQk+CQIJGglAACAJOAk+CSUAIAkmCT8JMglAAC4AIAkGCSMJPwAgCQcJJQlHCRoAIAkvCT4AIAkoCUcJJAlNCS8JPgkoCUAAIAk4CT4JAgkXCUAJJAkyCUcALgAuAA0ACiAcCTkJRwAgCSwJPgksCTAJQAAgCSoJPgkhCSMJPgkwCUcAIAkcCTAAIAkuCT4JHQlHACAJNgk/CTUJOAlICSgJPwkVACAJBQk4CSQJQAkyACAJJAkwACAJLgkyCT4AIAkkCU0JLwk+CQIJGgk+ACAJBQktCT8JLgk+CSgAIAkGCTkJRwAuIB0AIAAoCTkJRwAgCQUJOAlHACAgGQk4CU0JHwlHCR8JLglHCQIJHwlNIBkAIAkmCU0JLwk+CS8JGglHACAJJwk+CSEJOAAgCRUJSwkjCU0JLwk+ACAJKAlHCSQJTQkvCT4JJAAgCQUJOAlHCTIAPwApAA0ACgk5CT4AIAk5CT8JKAlNCSYJQQkkCU0JNQk+CRoJPgAgCQUJAgkXCT4JMAAgCS0JMglNCS8JPgktCTIJTQkvCT4JAgkoCT4AIAkqCUcJMgk1CTIJPgAgCSgJPgk5CUAAIAkFCSoJNQk+CSYAIAkVCUcJNQkzACAJDwkVCRoALgAuACAJLAk+CTMJPgk4CT4JOQlHCSwAIAkgCT4JFQkwCUcALgANAAoJLglBCQIJLAkICSQAIAkmCQIJFwkyACAJCQk4CTMJMgk/ACAJOQlLCSQJQAAgCW8JaQAgCTgJPgkyCUAALgAgCSQJTQkvCT4AIAk1CUcJMwk/ACAJFQlHCTUJMwAgCQYJIwk/ACAJFQlHCTUJMwAgCTYJPwk1CTgJSAkoCT8JFQk+CQIJLglBCTMJRwkaACAJLglBCQIJLAkIACAJNQk+CRoJMglAACAJOQlLCSQJQAAuACAJOAkXCTMJQAAgCSwJPgkzCT4JOAk+CTkJRwkCCRoJQAAgCRUJIQk1CR8AIAk2CT8JOAlNCSQALAAgCSwJQQkyCQIJJgAgCTkJPwkoCU0JJglBCSQJTQk1CT4JGgk+ACAJLAlBCTIJAgkmACAJBgk1CT4JHAAgCTYJPwk1CTgJRwkoCT4ALgANAAoJHAlHACAJFQlLCSMJJAk+CTkJQAAgCSgJRwkkCT4AIAkcCT4JOQk/CTAAIAkqCSMJRwAgCSwJSwkyCSMJPgkwACAJKAk+CTkJPwAgCSQJRwkaACAJOQk+ACAJKAlHCSQJPgAgCQUJFwkmCUAAIAk4CTkJHAAgCSoJIwlHACAJLAlLCTIJQQkoACAJHAk+CSQJSwAuACAJFQk+CTAJIwAgCQ8JFQkaACAgGQkGCTkJRwAgCRYJMAlHACAJJAkwACAJFQk+ACAJLAlLCTIJQQAgCSgJLwlHAD8gGQAgCQYJIwk/ACAJNQk/CRoJPgkwACAJDwkVCTIJTQkvCT4JNQkwACAJFQlLCSMJPwk5CUAAIAkuCU0JOQkjCUcJMgAuAC4JBQkXCSYJPwAgCS4JPgkdCU0JLwk+ACAJLgkoCT4JJAkyCUcAIAksCUsJMgkyCT4ALgAgCRUJPgk5CT8AIAk4CTAJFQk+CTAJPwAgCRUJPgkuCUcAIAk5CUsJJAAgCSgJPgk5CT8JJAAgCSgJQQk4CSQJTQkvCT4AIAkrCTwJPgkICTIJQAAgCRcJSwkzCT4AIAk5CUsJJAk+CSQALgAuCRUJPgkuACAJFQlLCSMAIAkVCTAJIwk+CTAAPwAgCRUJPgkuCQIAIAkVCT4AIAk5CUsJJAAgCSgJPgk5CT8JJAA/ACAJLwk+ACAJNQlHCTMJPwAgCS8JPgAgCSgJRwkkCU0JLwk+CSgJRwAgCTgJPgkCCRcJPwkkCTIJRwAgCQUJMAlHACAJLwk+ACAJKwk8CT4JLwkyCUAAIAkoCUEJOAkkCU0JLwk+ACAJFwlLCTMJPgAgCRUJMAlBCSgAIAkVCT4JLwAgCSAJRwk1CSQJPgkvACAJLgkCCSQJTQkwCT4JMgkvCT4JJAAuACAJHAkwACAJLwk+ACAJKwk8CT4JLwkyCUAAIAkuCQIJJAlNCTAJPgkyCS8JPgkkACAJKAlBCTgJJAlNCS8JPgAgCSoJIQlBCSgAIAkwCT4JOQkjCT4JMAAgCQUJOAkkCUAJMgAgCSQJMAAgCQYJFwAgCTIJPgk1CUAJKAAgCS4JAgkkCU0JMAk+CTIJLwk+CTIJPgAuACAJLQlBCRUJAgkqACAJHQk+CTIJPgAgCTkJSwkkCT4AIAktCUEJFQkCCSoAIAkvCT4AICAZCTgJTQkfCUcJHwkuCUcJAgkfIBkJNQkwAC4ADQAKCSoJPgkVCT8JOAlNCSQJPgkoCRoJTQkvCT4AIAkGCSQJAgkVCTUJPgkmCT8AIAkVCT4JMAk1CT4JLwk+ACAJFglBCSoJGgAgCTUJPgkiCTIJTQkvCT4AIAk5CUsJJAlNCS8JPgAuACAJKAlBCTgJJAlAACAJGAlBCTgJFglLCTAJQAAgCTkJSwkkACAJOQlLCSQJQAAuACAJBgkjCT8AIAkvCT4AIAk4CTAJFQk+CTAJGglHACAJFQk+CS8AIAkaCT4JMglBACAJOQlLCSQJRwAgCSQJMAAgCSoJPgkVCT8JOAlNCSQJPgkoCRoJTQkvCT4AIAkfCT8JLgAgCTIJPgAgCRUJTQkwCT8JFQlHCR8AIAkWCUcJMwk+CS8JMgk+ACAJLAlLCTIJNQk+CS8JGglHACwAIAksCT4JMwk+CTgJPgk5CUcJLAk+CQIJGgk+ACAJMAlLCRYJIAlLCRUAIAk4CTUJPgkyAC4ALgkFCTAJRwAgCS8JPgAgCSYJRwk2CT4JGglNCS8JPgAgCQ8JNQkiCU0JLwk+ACAJBgkkCQIJFQk1CT4JJgk/ACAJFQk+CTAJNQk+CS8JPgAgCTUJPgkiCTIJTQkvCT4AIAkFCTgJJAk+CSgJPgAgCRUJOAkyCU0JLwk+ACAJFQlNCTAJPwkVCUcJHwAgCRYJRwkzCSMJTQkvCT4JGglNCS8JPgAgCSwJPgkkCT4AIAkVCTAJJAk+AD8AIAk5CUcAIAk5CUsJJAk+ACAJFQk+CS4JPgAgCSgJLwlHAC4AIAkGCSMJPwAgCSwJPgkzCT4JOAk+CTkJRwksCT4JAgkoCUAAIAkPCRUJJgk+CRoAIAk4CT4JAgkXCUAJJAkyCUcADQAKIBwJLglAACAJLglBCQIJLAkICSQAIAkqCT4JFQk/CTgJTQkkCT4JKAkaCU0JLwk+ACAJHwk/CS4JMgk+ACAJFglHCTMJQQkoACAJJglHCSMJPgkwACAJKAk+CTkJPwAuIB0ADQAKCSQJTQkvCT4AIAk1CUcJMwlHACAJKgk+CTgJQQkoACAJJAlHACAJBgkcCRoJTQkvCT4AIAkmCT8JNQk4CT4JKgkwCU0JLwkCCSQAIAkqCT4JFQk/CTgJTQkkCT4JKAAgCR8JPwkuCSgJRwAgCS4JQQkCCSwJCAkkACAJKgk+CQoJMgAgCSAJRwk1CTIJRwkyCUcAIAkoCT4JOQk/ACwAIAkFCTAJRwAgCScJPgkhCTgJGgAgCSgJPgk5CT8ALgAgCRUJSwkjACAJLwk+ACAJBQkCCRcJPgkwCT4JNglAACAJFglHCTMJIwk+CTAAPwANAAoJLwk+ACAJLAk+CTMJPgk4CT4JOQlHCSwJPgkCCSgJPwAgCQUJKAlHCRUAIAkqCT8JIglNCS8JPgAgCSoJPgk5CT8JMglNCS8JPgAgCRgJIQk1CTIJTQkvCT4ALAAgCTYJPwk1CTgJSAkoCT8JFQAgCRgJIQk1CTIJRwAuACAJOQlHACAJNgk/CTUJOAlICSgJPwkVACAJLAk+CTMJPgk4CT4JOQlHCSwJPgkCCTgJPgkgCT8AIAkcCT8JNQAgCTkJPwAgCSYJTQkvCT4JLwkyCT4AIAkkCS8JPgkwAC4AIAkVCUcJNQkzACAJLAk+CTMJPgk4CT4JOQlHCSwJPgkCCRoJPgAgCQYJJglHCTYAIAkGCTkJRwAgCS4JTQk5CSMJQQkoACAJBgkqCTIJTQkvCT4AIAkcCT8JNQk+CRoJQAAgCSsJPAk/CRUJQAkwACAJKAAgCRUJMAkkCT4AIAkFCSgJRwkVACAJNgk/CTUJOAlICSgJPwkVCT4JAgkoCUAAIAkGCSoJMglHACAJMAkVCU0JJAAgCTgJPgkCCSEJMglHACAJBgk5CUcALgAgCTkJRwAgCRUJRwk1CTMAIAkGCSMJPwAgCRUJRwk1CTMAIAksCT4JMwk+CTgJPgk5CUcJLAk+CQIJGglNCS8JPgAgCSoJTQkwCUcJLgk+CSoJSwkfCT8ALgAgCRwJPwk1CT4JMgk+ACAJHAk/CTUAIAkmCUcJIwk+CTAJPwAgCTIJPgkWCUsAIAkuCT4JIwk4CUcALgANAAogHAkVCUcJNQkzACAJDwkVACAJBgkmCUcJNgAgCSYJTQkvCT4AIAk4CT4JOQlHCSwAIAkcCT8JNQk+CRoJQAk5CUAAIAkqCTAJTQk1CT4AIAkVCTAJIwk+CTAAIAkoCT4JOQk/IB0AIAk5CT4AIAk2CSwJTQkmACAJBgk5CUcAIAk2CT8JNQk4CUgJKAk/CRUJPgkaCT4ALgANAAoJLAk+CTMJPgk4CT4JOQlHCSwAIAkPCRUAIAkFCTgJAgAgCTUJTQkvCRUJTQkkCT8JLgkkCU0JNQAgCRUJPwAgCRwJTQkvCT4JGglAACAJEwkzCRYAIAkVCTAJQQkoACAJJglHCSMJTQkvCT4JGglAACAJFwkwCRwAIAkoCT4JOQk/AC4AIAkFCRYJTQkWCUcAIAkuCTkJPgkwCT4JNwlNCR8JTQkwACAJJAlNCS8JPgkCCSgJPgAgCTgJPgk5CUcJLAAgCS8JPgAgCSgJPgk1CT4JKAlAACAJEwkzCRYJJAlLAC4AIAkPCRUJHwk+ACAJLgk+CSMJQQk4ACwAIAkPCRUAIAkcCU0JNQkyCQIJJAAgCTUJPwkaCT4JMAAgCS4JKAk+CTYJQAAsACAJBQkCCRcJPgkwACAJLglBCRYJPgk2CUAAIAkYCUcJCgkoACAJDwkVACAJOAkCCRgJHwkoCT4AIAksCSgJNQkkCUsAICAcCTYJPwk1CTgJRwkoCT4gHQAuACAJBgkcACAJNgk/CTUJOAlHCSgJPgkaCT4AIAk1CT8JGgk+CTAAIAkVCUcJMglNCS8JPgAgCTYJPwk1CT4JLwAgCQ8JFQAgCTkJPwAgCTAJPgkcCRUJPwkvACAJKAk/CTAJTQkjCS8AIAkYCUcJJAkyCT4AIAkcCT4JJAAgCSgJPgk5CT8AIAkPCTUJIgk/ACAJKglNCTAJGgkCCSEAIAkkCT4JFQkkAC4AIAkPCRUJHwlNCS8JPgAgCS4JPgkjCTgJPgkaCU0JLwk+ACAJBgk1CT4JHAk+CSgJRwAgCQkJLQk+ACAJKglHCR8JMglHCTIJPgAgCS4JOQk+CTAJPgk3CU0JHwlNCTAAIAk2CT4JAgkkACAJOQlLCQoAIAk2CRUJJAlLACAJJAkwACAJNgk+CQIJJAAgCS4JOQk+CTAJPgk3CU0JHwlNCTAAIAkqCUcJHwlBACAJNgkVCSQJSwAuAA0ACgkPCRUAIAkuCT4JIwlBCTgAIAkqCUEJMAlNCSMAIAk2CT8JNQk+CRwJQAAgCSoJPgkwCU0JFQAtIB0JNgk/CTUJJAk/CTAJTQklIB0AIAkWCRoJPgkWCRoAIAktCTAJNQlBCRoAIAkVCTgJRwAgCTYJFQkkCUsALAAgCSQJRwk5CT8AIAkFCSgJRwkVACAJNQkwCU0JNwlHACAJOAkyCRcAIAk5CUcAIAkFCRwJQQkoACAJKAAgCTgJQQkfCTIJRwkyCUcAIAkVCUsJIQlHCRoALgAgCS4JTQk5CSMJQQkoCRoAIAksCT4JMwk+CTgJPgk5CUcJLAAgCSAJPgkVCTAJRwAgCTkJRwAgCSgJQQk4CSQJRwAgCTUJTQkvCRUJTQkkCT8JLgkkCU0JNQAgCSgJOAlBCSgAIAkPCRUAIAkaCS4JJAlNCRUJPgkwACAJBgk5CUcJJAAuAA0ACgkuCTAJPgkgCT8AIAkFCTgJTQkuCT8JJAlHCRoJQAAgCQYJFwAgCRwJTQkvCT4JKAlHACAJLgk5CT4JMAk+CTcJTQkfCU0JMAk+CSQJMglNCS8JPgAgCS4JMAk+CSAJPwAgCS4JPgkjCTgJPgkkACAJJwkXCScJFwkkACAJIAlHCTUJMglAACAJBQk2CU0JLwk+ACAJNQlNCS8JFQlNCSQJPwkuCSQJTQk1CT4JOAAgCS4JPgkdCUcAIAkqCU0JMAkjCT4JLgAsACAJJAlNCS8JPgkCCRoJPgAgCQYJJgkwCU0JNgAgCRgJRwkKCSgAIAkuCTkJPgkwCT4JNwlNCR8JTQkwACAJGAkhCTUJPgkvCRoJPgAgCSoJTQkwCS8JJAlNCSgAIAkVCTAJQQkvCT4ALgANAAoJHAkvACAJLgk5CT4JMAk+CTcJTQkfCU0JMAAuAA0ACg=="
}
function getData(jsonForm){
var el = document.querySelector('form[name='+jsonForm+']');
var inputs = el.querySelectorAll('input,select,textarea');
var data = {};
for(var i=0; i< inputs.length; i++){
switch(inputs[i].type){
case 'file':
var file = inputs[i].files[0];
if(file){
var oReader = new FileReader();
(function(i){
oReader.onload = function(e){
data[inputs[i].name] = e.target.result;
alert(JSON.stringify(data));
document.querySelector('p').innerHTML = JSON.stringify(data);
console.dir(data);
};
oReader.readAsDataURL(file);
})(i)
}
break;
case 'checkbox':
data[inputs[i].name] = inputs[i].checked;
break;
default:
data[inputs[i].name] = inputs[i].value;
}
}
document.querySelector('p').innerHTML = JSON.stringify(data);
}
form{width: 400px}
<form name="jsonForm">
<input type="text" name="firstname" value="John" />
<input type="text" name="surname" value="doe" />
<input type="email" name="email" value="abc#gmail.com" />
M: <input type="radio" name="gender" value="male" checked/>
F: <input type="radio" name="gender" value="female" />
subscribe: <input type="checkbox" name="subscribe" checked/>
<input type="file" name="upload" />
<select name="selection"><option value=M>M</option><option value=J>J</option></select>
<textarea name="description"></textarea>
</form>
<hr/>
<input type=button value="getData" onclick=getData('jsonForm')>
<p><p>
Late to the party, but this is how I do it:
(function getFormData(){
var form, inputs, formData = {}, outputdiv;
(function init(){
outputdiv = document.getElementById("output");
output();
})();
function build(){
form = document.querySelector("form"),
inputs = form.querySelectorAll("input, select, textarea"),
formData = {},
arr = [];
for(var i=0; i< inputs.length; i++){
var input = inputs[i];
input.onchange = function(){output();};
if(input.type=='radio'){
if(input.checked){
arr.push(input.name,input.value);
}
} else if(input.type=='checkbox'){
if(input.checked){
arr.push(input.name,input.value);
}
} else if(input.multiple){
//find each selected child
var options = input && input.options;
for (var o=0; o<options.length; o++) {
var opt = options[o],
val = (opt.value || opt.text)
if (opt.selected) {
arr.push(input.name,val);
}
}
} else {
arr.push(input.name,input.value);
}
}
var formdata = JSON.stringify(arr);
return formdata;
}
function output(){
outputdiv.innerHTML = build();
}
})()
<form>
<input type="text" name="text1" value="" />
<input type="text" name="text2" value="" />
<input type="email" name="text3" value="" />
<br />
<input type="radio" name="radio" value="radio1" />
<input type="radio" name="radio" value="radio2" />
<input type="radio" name="radio" value="radio3" />
<br />
<input type="checkbox" name="checkboxes" value="checkbox1" />
<input type="checkbox" name="checkboxes" value="checkbox2" />
<input type="checkbox" name="checkboxes" value="checkbox3" />
<br />
<textarea name="textarea"></textarea>
<br />
<select name="option">
<option value="">options</option>
<option>option text</option>
<option value="option 2 value">option 2 text</option>
<option>option 3 text</option>
</select>
<br />
<select multiple="true" name="options">
<option>opt multi 1</option>
<option value="opt multi 2 value">opt multi 2</option>
<option>opt multi 3</option>
</select>
</form>
<div id="output"></div>

How to deal with value of text input created dynamically?

Here's a link
<form onsubmit="return false"></form>
<label for="quantity">qantity</label>
<select name="quantity">
<script>
for (var i = 1; i < 81; i++) {
document.write("<option value='"+i+"'>"+i+"</option>");
};
</script>
</select>
<button id="next">next</button>
<form id="itemform" onsubmit="return false"></form>
<script>
$('#next').click(function(){
var quantity = ($('select[name=quantity]').val());
$('#itemform').html("");
for (var i = 0; i < quantity; i++) {
$('#itemform').append("<label for='itemname"+i+"'>itemname</label><br><input type='text' name='itemname"+i+"' id='itemname"+i+"'><br><label for='itemprice"+i+"'>itemprice</label><br><input type='text' name='itemprice"+i+"' id='itemprice"+i+"'><br><br>");
};
$('#itemform').append("<button id='submit'>submit</button>");
});
$('#submit').click(function(){
var item = {};
$('input[type=text]').each(function(){
var key = $(this).attr('name');
var value = $(this).val();
item [key] = value;
});
console.log(item)
});
It creates text inputs as many as selected.
And then, it makes object like {itemname1 : "an awesome thing", ...}.
Creating input works very well but it doesn't make object.
It makes object input that doesn't created dynamically.
<form onsubmit="return false">
<input type="text" name="first">
<input type="text" name="second">
<input type="submit" id="submit">
</form>
<p id="res"></p>
<script>
$('#submit').click(function(){
var item = {};
$('input[type=text]').each(function(){
var key = $(this).attr('name');
var value = $(this).val();
item [key] = value;
});
console.log(item)
});
</script>
Why doesn't it work as I expected?
$('#submit') doesn't exist in your example. I replaced it with $('#itemform').submit() instead, and it seems to be logging a giant object. See the updated jfiddle here.
$('#itemform').submit(function(e){
e.preventDefault();
var item = {};
$('input[type=text]').each(function(){
var key = $(this).attr('name');
var value = $(this).val();
item [key] = value;
});
console.log(item)
});
Also, if you're looking at improving how items are stored, I updated the jsfiddle again here to show you how you can group items:
$(document).ready(function() {
$('#next').click(function(){
var quantity = ($('select[name=quantity]').val());
$('#itemform').html("");
for (var i = 0; i < quantity; i++) {
$('#itemform').append("<div class='item' data-item='" + i + "'><label for='itemname"+i+"'>itemname</label><br><input type='text' name='name' id='itemname"+i+"'><br><label for='itemprice"+i+"'>itemprice</label><br><input type='text' name='price' id='itemprice"+i+"'><br><br></div>");
};
$('#itemform').append("<button id='submit'>submit</button>");
});
$('#itemform').submit(function(e){
e.preventDefault();
var items = {};
$('#itemform div.item').each(function(){
var item = {};
$(this).find('input[type=text]').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
item [key] = value;
});
items[$(this).data('item')] = item;
});
console.log(items)
});
});
This yields a much better object you can work with:
{
"0": {
"name": "item1name",
"price": "item1price"
},
"1": {
"name": "item2name",
"price": "item2price"
},
"2": {
"name": "item3 here",
"price": "item3 has a big price"
}
}
Don't attach your processing function to your form's submit button's click event. Instead, use the form's submit event.
Also, even though it doesn't make a difference syntax wise, for readability's sake, you might want to add a ";" after "console.log(item)".
$('#itemform').submit(function(){
var item = {};
$('input[type=text]').each(function(){
var key = $(this).attr('name');
var value = $(this).val();
item [key] = value;
});
console.log(item);
return false;
});
Also, no need for a onSubmit property on your form in your case, just return "false" with the processing function attached to your form's submit event.
<form id="itemform"></form>
See the updated fiddle here.

access arbitrary property from object

I have a set of nesting json object like this:
var obj = {
name: "student",
contact: {
phone: "22222",
fax: "33333",
...
},
...
}
And I have these text fields:
<input type="text" name="name" />
<input type="text" name="contact_phone" />
<input type="text" name="contact_fax" />
...
Now I want to fill these fields with appropriate property from above object. My question is how can I access anonymous property from that object?
For example suppose I have this jquery code:
$("#formID").find("input").each(function(index) {
fieldName = $(this).attr("name");
var namePart = fieldName.split("_");
//I want something like this: console.log(obj.namePart[0].namePart[1])
});
Use obj["propertyName"]
obj[namePart[0]][namePart[1]]
$('#formID').find("input").each(function(index) {
fieldName = $(this).attr("name");
var namePart;
if(fieldName.indexOf('_') > -1){
namePart = fieldName.split("_");
console.log(obj[namePart[0]][namePart[1]])
}
else{
namePart = fieldName;
console.log(obj[namePart])
}
});
*Note: The property is not anonymous. If your run obj["propertyName"] on an object with no such property it will return undefined.
<form ID="formID">
<input type="text" name="name" />
<input type="text" name="contact_phone" />
<input type="text" name="contact_fax" />
</form>
$("#formID").find("input").each(function() {
fieldName = $(this).attr("name");
namePart = fieldName.split("_");
if(namePart.length ==1 && namePart[0]=="name"){
$(this).val(obj.name);
}
else if(namePart.length>1){
$(this).val(obj[namePart[0]][namePart[1]]);
}
//I want something like this: console.log(obj.namePart[0].namePart[1])
});
http://jsfiddle.net/57vL6b0w/
Edit: Sorry about that I misunderstood the question. What you are looking for is something like this.
var obj = {
name: "student",
contact: {
phone: "22222",
fax: "33333"
}
};
$('#formID').("input").each(function(index) {
fieldName = $(this).attr("name");
var namePart = fieldName.split("_");
var arbitraryVal = obj;
for (var part in namePart) {
if (arbitraryVal.hasOwnProperty(namePart[part])) {
arbitraryVal = arbitraryVal[namePart[part]];
continue;
}
arbitraryVal = null;
break;
}
if (typeof $(this).val(arbitraryVal) !== 'undefined') {
$(this).val(arbitraryVal);
}
});
recusivly searches an object for each name part. If the name part is
contact_phone It will look for obj.contact.phone if it is something_else_with_lots_of_underscores it will look for obj.something.else.with.lots.of.underscores
JS FIDDLE

Getting HTML form values

How can I get the value of an HTML form to pass to JavaScript?
Is this correct? My script takes two arguments one from textbox, one from the dropdown box.
<body>
<form name="valform" action="" method="POST">
Credit Card Validation: <input type="text" id="cctextboxid" name="cctextbox"><br/>
Card Type: <select name="cardtype" id="cardtypeid">
<option value="visa">Visa</option>
<option value="mastercard">MasterCard</option>
<option value="discover">Discover</option>
<option value="amex">Amex</option>
<option value="diners">Diners Club</option>
</select><br/>
<input type="button" name="submit" value="Verify Credit Card" onclick="isValidCreditCard(document.getElementById('cctextboxid').value,document.getElementById('cardtypeid').value)" />
</body>
HTML:
<input type="text" name="name" id="uniqueID" value="value" />
JS:
var nameValue = document.getElementById("uniqueID").value;
If you want to retrieve the form values (such as those that would be sent using an HTTP POST) you can use:
JavaScript
function getData(form) {
var formData = new FormData(form);
// iterate through entries...
for (var pair of formData.entries()) {
console.log(pair[0] + ": " + pair[1]);
}
// ...or output as an object
console.log(Object.fromEntries(formData));
}
document.getElementById("myForm").addEventListener("submit", function (e) {
e.preventDefault();
getData(e.target);
});
Example: https://codepen.io/kevinfarrugia/pen/Wommgd?editors=1111
Alternatively you could use the below less recommended options:
form-serialize (https://code.google.com/archive/p/form-serialize/)
serialize(document.forms[0]);
jQuery
$("form").serializeArray()
I found this the most elegant solution.
function handleSubmit(e) {
e.preventDefault();
const formData = new FormData(e.target);
const formProps = Object.fromEntries(formData);
}
Here is an example from W3Schools:
function myFunction() {
var elements = document.getElementById("myForm").elements;
var obj ={};
for(var i = 0 ; i < elements.length ; i++){
var item = elements.item(i);
obj[item.name] = item.value;
}
document.getElementById("demo").innerHTML = JSON.stringify(obj);
}
The demo can be found here.
document.forms will contain an array of forms on your page. You can loop through these forms to find the specific form you desire.
var form = false;
var length = document.forms.length;
for(var i = 0; i < length; i++) {
if(form.id == "wanted_id") {
form = document.forms[i];
}
}
Each form has an elements array which you can then loop through to find the data that you want. You should also be able to access them by name
var wanted_value = form.someFieldName.value;
jsFunction(wanted_value);
This is a developed example of https://stackoverflow.com/a/41262933/2464828
Consider
<form method="POST" enctype="multipart/form-data" onsubmit="return check(event)">
<input name="formula">
</form>
Let us assume we want to retrieve the input of name formula. This can be done by passing the event in the onsubmit field. We can then use FormData to retrieve the values of this exact form by referencing the SubmitEvent object.
const check = (e) => {
const form = new FormData(e.target);
const formula = form.get("formula");
console.log(formula);
return false
};
The JavaScript code above will then print the value of the input to the console.
If you want to iterate the values, i.e., get all the values, then see https://developer.mozilla.org/en-US/docs/Web/API/FormData#Methods
My 5 cents here, using form.elements which allows you to query each field by it's name, not only by iteration:
const form = document.querySelector('form[name="valform"]');
const ccValidation = form.elements['cctextbox'].value;
const ccType = form.elements['cardtype'].value;
A one liner for ES6
getFormData = (selector) => Object.fromEntries(new FormData(document.querySelector(selector)))
console.log('Output of getFormData:')
console.log(getFormData('#myTargetForm'))
<!DOCTYPE html>
<html>
<body>
<h2>Get Form Data as Javascript Object</h2>
<form id="myTargetForm">
<label for="fname">First name:</label><br>
<input type="text" id="fname" name="fname" value="John"><br>
<label for="lname">Last name:</label><br>
<input type="text" id="lname" name="lname" value="Doe"><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
Define this function in your Javascript:
getFormData = (selector) => Object.fromEntries(new FormData(document.querySelector(selector)))
Then just call with any selector e.g.:
getFormData('#myTargetForm')
Expanding on Atrur Klesun's idea... you can just access it by its name if you use getElementById to reach the form. In one line:
document.getElementById('form_id').elements['select_name'].value;
I used it like so for radio buttons and worked fine. I guess it's the same here.
This is the answer of your question.
You can pass the values of the form fields to the function by using this.<<name of the field>>.value.
And also changed input submit to button submit. Called the function from form.
<body>
<form name="valform" method="POST" onsubmit="isValidCreditCard(this.cctextbox.value, this.cardtype.value)">
Credit Card Validation: <input type="text" id="cctextboxid" name="cctextbox"><br/>
Card Type:
<select name="cardtype" id="cardtypeid">
...
</select>
<br/>
<button type="submit">Verify Credit Card</button>
</body>
Technically you can do it in your function by using document.getElementById("cctextboxid"). But his solution is concise and simple code.
I know this is an old post but maybe someone down the line can use this.
// use document.form["form-name"] to reference the form
const ccForm = document.forms["ccform"];
// bind the onsubmit property to a function to do some logic
ccForm.onsubmit = function(e) {
// access the desired input through the var we setup
let ccSelection = ccForm.ccselect.value;
console.log(ccSelection);
e.preventDefault();
}
<form name="ccform">
<select name="ccselect">
<option value="card1">Card 1</option>
<option value="card2">Card 2</option>
<option value="card3">Card 3</option>
</select>
<button type="submit">Enter</button>
</form>
Please try to change the code as below:
<form
onSubmit={e => {
e.preventDefault();
e.stopPropagation();
const elements = Array.from(e.currentTarget);
const state = elements.reduce((acc, el) => {
if (el.name) {
acc[el.name] = el.value;
}
return acc;
}, {});
console.log(state); // {test: '123'}
}}
>
<input name='test' value='123' />
</form>
Several easy-to-use form serializers with good documentation.
In order of Github stars,
jquery.serializeJSON
jquery-serialize-object
form2js
form-serialize
<form id='form'>
<input type='text' name='title'>
<input type='text' name='text'>
<input type='email' name='email'>
</form>
const element = document.getElementByID('#form')
const data = new FormData(element)
const form = Array.from(data.entries())
/*
form = [
["title", "a"]
["text", "b"]
["email", "c"]
]
*/
for (const [name, value] of form) {
console.log({ name, value })
/*
{name: "title", value: "a"}
{name: "text", value: "b"}
{name: "email", value: "c"}
*/
}
It's easy with one for-of loop you can get all field values even checkboxes values also.
In your HTML you should bind a handlSubmit() on your forms onsubmit event
<form name="contact_form"
id="contact-form"
class="form-controller"
onsubmit="handleSubmit(event)"
>
in your javascript your code should apply the following logic no matter what name your assigned to your fields.
const handleSubmit = (event)=> {
event.preventDefault();
const formData = new FormData(event.target);
formObj = {};
for (const [fieldName] of formData) {
const fieldValue = formData.getAll(fieldName);
formObj[fieldName] = fieldValue.length == 1 ? fieldValue.toString() : fieldValue
}
console.log('formObj',formObj)
}
Quick solution to serialize a form without any libraries
function serializeIt(form) {
return (
Array.apply(0, form.elements).map(x =>
(
(obj =>
(
x.type == "radio" ||
x.type == "checkbox"
) ?
x.checked ?
obj
:
null
:
obj
)(
{
[x.name]:x.value
}
)
)
).filter(x => x)
);
}
function whenSubmitted(e) {
e.preventDefault()
console.log(
JSON.stringify(
serializeIt(document.forms[0]),
4, 4, 4
)
)
}
<form onsubmit="whenSubmitted(event)">
<input type=text name=hiThere value=nothing>
<input type=radio name=okRadioHere value=nothin>
<input type=radio name=okRadioHere1 value=nothinElse>
<input type=radio name=okRadioHere2 value=nothinStill>
<input type=checkbox name=justAcheckBox value=checkin>
<input type=checkbox name=justAcheckBox1 value=checkin1>
<input type=checkbox name=justAcheckBox2 value=checkin2>
<select name=selectingSomething>
<option value="hiThere">Hi</option>
<option value="hiThere1">Hi1</option>
<option value="hiThere2">Hi2</option>
<option value="hiThere3">Hi3</option>
</select>
<input type=submit value="click me!" name=subd>
</form>
<script>
var inputs = document.getElementById("form_id_here").elements;
for (i = 0; i < inputs.length; i++) {
if (inputs[i].type === "text" || inputs[i].type === "textarea") {
console.log(inputs[i].value); // Get value of input tag which you have entered.
}
}
</script>
Some answers above didn't cater for forms with multiple fields with the same name e.g.multiple <input name="categories[]"> so I made this quickly. It expects field with the same name that you want to collect as an array to end in [] as a convention but could be updated to handle other scenarios.
function getFormValues(form) {
const formData = new FormData(form);
return Array.from(formData.entries()).reduce((prev, [inputName, val]) => {
return {
...prev,
[inputName]: inputName.endsWith('[]')
? prev[inputName]
? [...prev[inputName], val]
: [val]
: val,
};
}, {});
}
// alternative if you don't like reducers and nested ternary statements
function getFormValues(form) {
const formData = new FormData(form);
const values = {};
for (const [inputName, val] of formData.entries()) {
if (inputName.endsWith('[]')) {
values[inputName] = values[inputName] ? [...values[inputName], val] : [val];
} else {
values[inputName] = val;
}
}
return values;
}
// then attach this to form submit
function onSubmit(e) {
e.preventDefault();
const values = getFormValues(e.target);
// etc...
}
values gives something like { "single": "something", "categories[]": ["one", "two"] }
<input type="text" id="note_text" />
let value = document.getElementById("note_text").value;

Categories