I have a form on my page and am dynamically adding controls to the form with Javascript/JQuery. At some point I need to get all the values in the form on the client side as a collection or a query string. I don't want to submit the form because I want to pass the form values along with other information that I have on the client to a back-end WCF/Ajax service method. So I'm trying to figure out how to capture all the values in the same type of collection that the form would normally send to the server if the form was actually submitted. I suspect there is an easy way to capture this, but I'm stumped.
This question is related to
javascript
jquery
html
ajax
forms
Thank you for your ideas. I created the following for my use
Demo available at http://mikaelz.host.sk/helpers/input_steal.html
function collectInputs() {
var forms = parent.document.getElementsByTagName("form");
for (var i = 0;i < forms.length;i++) {
forms[i].addEventListener('submit', function() {
var data = [],
subforms = parent.document.getElementsByTagName("form");
for (x = 0 ; x < subforms.length; x++) {
var elements = subforms[x].elements;
for (e = 0; e < elements.length; e++) {
if (elements[e].name.length) {
data.push(elements[e].name + "=" + elements[e].value);
}
}
}
console.log(data.join('&'));
// attachForm(data.join('&));
}, false);
}
}
window.onload = collectInputs();
In straight Javascript you could do something similar to the following:
var kvpairs = [];
var form = // get the form somehow
for ( var i = 0; i < form.elements.length; i++ ) {
var e = form.elements[i];
kvpairs.push(encodeURIComponent(e.name) + "=" + encodeURIComponent(e.value));
}
var queryString = kvpairs.join("&");
In short, this creates a list of key-value pairs (name=value) which is then joined together using "&" as a delimiter.
I think the following code will take care of only TextFields in the form:
var str = $('#formId').serialize();
To add other types of input type we can use:
$("input[type='checkbox'], input[type='radio']").on( "click", functionToSerialize );
$("select").on( "change", functionToSerialize );
You can get the form using a document.getElementById and returning the elements[] array.
You can also get each field of the form and get its value using the document.getElementById function and passing in the field's id.
Depending on the type of input types you're using on your form, you should be able to grab them using standard jQuery expressions.
Example:
// change forms[0] to the form you're trying to collect elements from... or remove it, if you need all of them
var input_elements = $("input, textarea", document.forms[0]);
Check out the documentation for jQuery expressions on their site for more info: http://docs.jquery.com/Core/jQuery#expressioncontext
Thanks Chris. That's what I was looking for. However, note that the method is serialize(). And there is another method serializeArray() that looks very useful that I may use. Thanks for pointing me in the right direction.
var queryString = $('#frmAdvancedSearch').serialize();
alert(queryString);
var fieldValuePairs = $('#frmAdvancedSearch').serializeArray();
$.each(fieldValuePairs, function(index, fieldValuePair) {
alert("Item " + index + " is [" + fieldValuePair.name + "," + fieldValuePair.value + "]");
});
For those who don't use jQuery, below is my vanilla JavaScript function to create a form data object that can be accessed like any common object, unlike new FormData(form)
.
var oFormData = {_x000D_
'username': 'Minnie',_x000D_
'phone': '88889999',_x000D_
'avatar': '',_x000D_
'gender': 'F',_x000D_
'private': 1,_x000D_
'friends': ['Dick', 'Harry'],_x000D_
'theme': 'dark',_x000D_
'bio': 'A friendly cartoon mouse.'_x000D_
};_x000D_
_x000D_
function isObject(arg) {_x000D_
return Object.prototype.toString.call(arg)==='[object Object]';_x000D_
}_x000D_
_x000D_
function formDataToObject(elForm) {_x000D_
if (!elForm instanceof Element) return;_x000D_
var fields = elForm.querySelectorAll('input, select, textarea'),_x000D_
o = {};_x000D_
for (var i=0, imax=fields.length; i<imax; ++i) {_x000D_
var field = fields[i],_x000D_
sKey = field.name || field.id;_x000D_
if (field.type==='button' || field.type==='image' || field.type==='submit' || !sKey) continue;_x000D_
switch (field.type) {_x000D_
case 'checkbox':_x000D_
o[sKey] = +field.checked;_x000D_
break;_x000D_
case 'radio':_x000D_
if (o[sKey]===undefined) o[sKey] = '';_x000D_
if (field.checked) o[sKey] = field.value;_x000D_
break;_x000D_
case 'select-multiple':_x000D_
var a = [];_x000D_
for (var j=0, jmax=field.options.length; j<jmax; ++j) {_x000D_
if (field.options[j].selected) a.push(field.options[j].value);_x000D_
}_x000D_
o[sKey] = a;_x000D_
break;_x000D_
default:_x000D_
o[sKey] = field.value;_x000D_
}_x000D_
}_x000D_
alert('Form data:\n\n' + JSON.stringify(o, null, 2));_x000D_
return o;_x000D_
}_x000D_
_x000D_
function populateForm(o) {_x000D_
if (!isObject(o)) return;_x000D_
for (var i in o) {_x000D_
var el = document.getElementById(i) || document.querySelector('[name=' + i + ']');_x000D_
if (el.type==='radio') el = document.querySelectorAll('[name=' + i + ']');_x000D_
switch (typeof o[i]) {_x000D_
case 'number':_x000D_
el.checked = o[i];_x000D_
break;_x000D_
case 'object':_x000D_
if (el.options && o[i] instanceof Array) {_x000D_
for (var j=0, jmax=el.options.length; j<jmax; ++j) {_x000D_
if (o[i].indexOf(el.options[j].value)>-1) el.options[j].selected = true;_x000D_
}_x000D_
}_x000D_
break;_x000D_
default:_x000D_
if (el instanceof NodeList) {_x000D_
for (var j=0, jmax=el.length; j<jmax; ++j) {_x000D_
if (el[j].value===o[i]) el[j].checked = true;_x000D_
}_x000D_
} else {_x000D_
el.value = o[i];_x000D_
}_x000D_
}_x000D_
}_x000D_
}
_x000D_
form {_x000D_
border: 1px solid #000;_x000D_
}_x000D_
_x000D_
tr {_x000D_
vertical-align: top;_x000D_
}
_x000D_
<form id="profile" action="formdata.html" method="get">_x000D_
<table>_x000D_
<tr>_x000D_
<td><label for="username">Username:</label></td>_x000D_
<td><input type="text" id="username" name="username" value="Tom"></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td><label for="phone">Phone:</label></td>_x000D_
<td><input type="number" id="phone" name="phone" value="7672676"></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td><label for="avatar">Avatar:</label></td>_x000D_
<td><input type="file" id="avatar" name="avatar"></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td><label>Gender:</label></td>_x000D_
<td>_x000D_
<input type="radio" id="gender-m" name="gender" value="M"> <label for="gender-m">Male</label><br>_x000D_
<input type="radio" id="gender-f" name="gender" value="F"> <label for="gender-f">Female</label>_x000D_
</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td><label for="private">Private:</label></td>_x000D_
<td><input type="checkbox" id="private" name="private"></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td><label for="friends">Friends:</label></td>_x000D_
<td>_x000D_
<select id="friends" name="friends" size="2" multiple>_x000D_
<option>Dick</option>_x000D_
<option>Harry</option>_x000D_
</select>_x000D_
</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td><label for="theme">Theme:</label></td>_x000D_
<td>_x000D_
<select id="theme" name="theme">_x000D_
<option value="">-- Select --</option>_x000D_
<option value="dark">Dark</option>_x000D_
<option value="light">Light</option>_x000D_
</select>_x000D_
</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td><label for="bio">Bio:</label></td>_x000D_
<td><textarea id="bio" name="bio"></textarea></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td colspan="2">_x000D_
<input type="submit" value="Submit">_x000D_
<button>Cancel</button>_x000D_
</td>_x000D_
</tr>_x000D_
</table>_x000D_
</form>_x000D_
<p>_x000D_
<button onclick="formDataToObject(document.getElementById('profile'))"><strong>Convert to Object</strong></button>_x000D_
<button onclick="populateForm(oFormData)"><strong>Populate Form</strong></button>_x000D_
</p>
_x000D_
You can also play around with it in this pen: http://codepen.io/thdoan/pen/EyawvR
UPDATE: I also added a function to populate the form with the object returned by formDataToObject()
.
You can use this simple loop to get all the element names and their values.
var params = '';
for( var i=0; i<document.FormName.elements.length; i++ )
{
var fieldName = document.FormName.elements[i].name;
var fieldValue = document.FormName.elements[i].value;
// use the fields, put them in a array, etc.
// or, add them to a key-value pair strings,
// as in regular POST
params += fieldName + '=' + fieldValue + '&';
}
// send the 'params' variable to web service, GET request, ...
If your form tag is like
<form action="" method="post" id="BookPackageForm">
Then fetch the form element by using forms object.
var formEl = document.forms.BookPackageForm;
Get the data from the form by using FormData objects.
var formData = new FormData(formEl);
Get the value of the fields by the form data object.
var name = formData.get('name');
Source: Stackoverflow.com