How an I get all form elements (input, textarea & select) with jQuery?
Is there an easy way (without listing them all separately) in jquery to select all form elements and only form elements. I can’t use children() etc because the form contains other HTML. E.g:
15 Answers 15
Edit: As pointed out in comments (Mario Awad & Brock Hensley), use .find to get the children
forms also have an elements collection, sometimes this differs from children such as when the form tag is in a table and is not closed.
var summary = []; $('form').each(function () < summary.push('Form ' + this.id + ' has ' + $(this).find(':input').length + ' child(ren).'); summary.push('Form ' + this.id + ' has ' + this.elements.length + ' form element(s).'); >); $('#results').html(summary.join('
'));
May be :input selector is what you want
To achieve the best performance when using :input to select elements, first select the elements using a pure CSS selector, then use .filter(«:input»).
Thanks although after reading: api.jquery.com/input-selector performance being an issue I may as well list them. Good to know its possible though
Is it just me or does this not work for select ? EDIT: nevermind, works with select if I use find(‘:input’)
You have to use «find» instead of «filter» in here as «filter» cannot work on a single element (in this case the «this» element). Using «filter» you will not be able to select any form elements and not only «select» elements. Thanks for @Brock Hensley for pointing this out.
How about large forms? I have a huge form with more than 4000+ elements in it, and this selector is very slow. In the specification is written that :input is not browser optimized by the CSS3, so does not work for me :/ . Any other ideas?
@VasilPopov The above may be too slow for you. You could try couple of solutions, either way you need to group fewer elements and select them.
The below code helps to get the details of elements from the specific form with the form id,
$('#formId input, #formId select').each( function(index) < var input = $(this); alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') + 'Value: ' + input.val()); >);
The below code helps to get the details of elements from all the forms which are place in the loading page,
$('form input, form select').each( function(index) < var input = $(this); alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') + 'Value: ' + input.val()); >);
The below code helps to get the details of elements which are place in the loading page even when the element is not place inside the tag,
$('input, select').each( function(index) < var input = $(this); alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') + 'Value: ' + input.val()); >);
NOTE: We add the more element tag name what we need in the object list like as below,
Example: to get name of attribute "textarea", $('input, select, textarea').each( function(index) < var input = $(this); alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') + 'Value: ' + input.val()); >);
Why this takes all the values and options of a select element, rather than giving the value of something that has been select or otherwise blank. ?
These selectors ignore radiobutton and checkboxes. which can be selected using «formSelector:input» . also it is not possible to read state of checkbox and radio buttons with .val() it has to be verified with «:checked»
If you have additional types, edit the selector:
var formElements = new Array(); $("form :input").each(function()< formElements.push($(this)); >);
All form elements are now in the array formElements.
JQuery serialize function makes it pretty easy to get all form elements.
$("form").serialize(); //get all form elements at once //result would be like this: single=Single&multiple=Multiple&multiple=Multiple3&check=check2&radio=radio1
To compound on that idea: you can use something like this to make all form elements accessible.
Data = $('form').serialize().split('&'); for(i in Data) < Data[i] = Data[i].split('='); Fields[ Data[i][0] ] = [ Data[i][1], $('form *[name="' + Data[i][0] + '"]').eq(0) ]; >console.log(Fields); // The result would be a multi-dimensional array you could loop through Fields[Field_Name] = [Field_Value, Field_Object]
Note: This will only work with named fields as serialize() will ignore all others. Any fields with duplicate names will be ignored. You could make a multi-dimensional array if multiple fields use the same name.
jQuery keeps a reference to the vanilla JS form element, and this contains a reference to all of the form’s child elements. You could simply grab the reference and proceed forward:
var someForm = $('#SomeForm'); $.each(someForm[0].elements, function(index, elem)< //Do something here. >);
As an alternative, Object.entries($(‘form’).get(0).elements).reduce((arr, [_, el]) => el.name ? Object.assign(arr, < [el.name]: el.value >) : arr, <>) will get you an object containing name:value of all form elements with non-empty name.
For the record: The following snippet can help you to get details about input, textarea, select, button, a tags through a temp title when hover them.
$( 'body' ).on( 'mouseover', 'input, textarea, select, button, a', function() < var $tag = $( this ); var $form = $tag.closest( 'form' ); var title = this.title; var var name = this.name; var value = this.value; var type = this.type; var cls = this.className; var tagName = this.tagName; var options = []; var hidden = []; var formDetails = ''; if ( $form.length ) < $form.find( ':input[type="hidden"]' ).each( function( index, el ) < hidden.push( "\t" + el.name + ' = ' + el.value ); >); var formName = $form.prop( 'name' ); var formTitle = $form.prop( 'title' ); var formId = $form.prop( 'id' ); var formClass = $form.prop( 'class' ); formDetails += "\n\nFORM NAME: " + formName + "\nFORM TITLE: " + formTitle + "\nFORM ID: " + formId + "\nFORM CLASS: " + formClass + "\nFORM HIDDEN INPUT:\n" + hidden.join( "\n" ); > var tempTitle = "TAG: " + tagName + "\nTITLE: " + title + "\nID: " + id + "\nCLASS: " + cls; if ( 'SELECT' === tagName ) < $tag.find( 'option' ).each( function( index, el ) < options.push( el.value ); >); tempTitle += "\nNAME: " + name + "\nVALUE: " + value + "\nTYPE: " + type + "\nSELECT OPTIONS:\n\t" + options; > else if ( 'A' === tagName ) < tempTitle += "\nHTML: " + $tag.html(); >else < tempTitle += "\nNAME: " + name + "\nVALUE: " + value + "\nTYPE: " + type; >tempTitle += formDetails; $tag.prop( 'title', tempTitle ); $tag.on( 'mouseout', function() < $tag.prop( 'title', title ); >) > );
Check all elements in form with Javascript
I know javascript in the beginning level, but I have a problem. I have 7 input elements in a form and I want all of them to be filled. I came up with this idea but it looks disgusting. Can someone help me how to check whether all form elements are filled or not?
Slightly less disgusting — take advantage of the falsiness of «», and make your if statement: if (!x || !y || !z || !q || !w || !e || !e)
5 Answers 5
This is the simple and dirty way.
A better way is to update a validation message that the fields are required.
function validateForm() < var fields = ["name, phone", "compname", "mail", "compphone", "adres", "zip"] var i, l = fields.length; var fieldname; for (i = 0; i < l; i++) < fieldname = fields[i]; if (document.forms["register"][fieldname].value === "") < alert(fieldname + " can not be empty"); return false; >> return true; >
Yes, it still counts as empty. The placeholder doesn’t change the value of an input element, only how it displays.
With some simple vanilla JS, you can handle this in a lot more simplified way:
function validateForm() < var form = document.getElementById("register"), inputs = form.getElementsByTagName("input"), input = null, flag = true; for(var i = 0, len = inputs.length; i < len; i++) < input = inputs[i]; if(!input.value) < flag = false; input.focus(); alert("Please fill all the inputs"); break; >> return(flag); >
Then make sure you return the function within your form, either inline (bad practice):
Or in a more unobtrusive way:
window.onload = function() < var form = document.getElementById("register"); form.onsubmit = function()< var inputs = form.getElementsByTagName("input"), input = null, flag = true; for(var i = 0, len = inputs.length; i < len; i++) < input = inputs[i]; if(!input.value) < flag = false; input.focus(); alert("Please fill all the inputs"); break; >> return(flag); >; >;
Event Management
JavaScript Validation
Name: Age: Phone:
You can use this easy method to validate all fields of form.
//Declare variables var 1, 2, 3, 4, 5, 6, 7; 1 = document.getElementById("Field Id"); 2 = document.getElementById("Field Id"); 3 = document.getElementById("Field Id"); 4 = document.getElementById("Field Id"); //Define variable values 5 = document.getElementById("Field Id"); 6 = document.getElementById("Field Id"); 7 = document.getElementById("Field Id"); //Check if any of the fields are empty If (1 == "" || 2 == "" || 3 == "" || 4 == "" || 5 == "" || 6 == "" || 7 == "") < alert("One or more fields are empty!"); //Other code >
I used this for my own form and it works fine while not taking up to much space or looking too «ugly». It works for all field elements and checks the value entered.
Getting all form values by JavaScript
And the onchange action of any input in form I need to get a JavaScript string, for example » status=1&size=big » for using in httprequest. Does there exist something in JavaScript that will take all form values when one of form inputs will be changed? I used
adaneo: form is change, but i need to get all values from all input fields in form. Jason, i don’t use jquery in this project. epascarello yes but I was hoping that there is exist some javascript included solution, I thought that is usual requirement.
11 Answers 11
For input fields you could use ECMAScript 6 like the following:
Get your form in a constant:
const form = document.querySelector('form')
Object.values(form).reduce((obj,field) => < obj[field.name] = field.value; return obj >, <>)
The above snippet will produce an object with the input name as the key and its value.
This solution looks beautiful, but still has some issues: 1) There is still a big user base with browsers that don’t support Object.values yet 2) the result includes values that are not form inputs. You could use Object.values(form.elements) to solve this. Would upvote if it had this fix and was based on Object.keys() instead 🙂
Here is a working fiddle in vanilla JavaScript, but you need to add a serialize utility function. This works exactly like $(‘form’).serialize() in jQuery.
var data; function serialize(form) < if (!form || form.nodeName !== "FORM") < return; >var i, j, q = []; for (i = form.elements.length - 1; i >= 0; i = i - 1) < if (form.elements[i].name === "") < continue; >switch (form.elements[i].nodeName) < case 'INPUT': switch (form.elements[i].type) < case 'text': case 'hidden': case 'password': case 'button': case 'reset': case 'submit': q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value)); break; case 'checkbox': case 'radio': if (form.elements[i].checked) < q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value)); >break; > break; case 'file': break; case 'TEXTAREA': q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value)); break; case 'SELECT': switch (form.elements[i].type) < case 'select-one': q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value)); break; case 'select-multiple': for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) < if (form.elements[i].options[j].selected) < q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].options[j].value)); >> break; > break; case 'BUTTON': switch (form.elements[i].type) < case 'reset': case 'submit': case 'button': q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value)); break; >break; > > data = q.join("&"); >
And change your form onchange to
I tested it and am getting «size=small&status=0» in the console.
How to loop through elements of forms with JavaScript?
How can I loop over the input elements in the form (in order to perform some validation on them)? I’d prefer to use only pure JavaScript, not jQuery or another library. I’d also like to limit the iteration to form elements, not any other elements which may be added to the form.
@DanDascalescu As you can see in the HTML, these form field doesn’t have different names. Thus, it is not duplicate.
7 Answers 7
A modern ES6 approach. The form has a property elements which is a reference to all the input elements. Select the form with any method you like. Use the spread operator to convert the HTMLFormControlsCollection to an Array. Then the forEach method is available. For example [. form.elements].forEach
Update: Array.from is a nicer alternative to the spread operator Array.from(form.elements) it’s slightly clearer behaviour.
An example below iterates over every input in the form.
You can filter out input types with the type property formInputs.filter((input) => input.type !== «submit»)
const forms = document.querySelectorAll('form'); const form = forms[0]; Array.from(form.elements).forEach((input) => < console.log(input); >);
Input Form Selection
You need to get a reference of your form, and after that you can iterate the elements collection. So, assuming for instance:
You will have something like:
var elements = document.getElementById("my-form").elements; for (var i = 0, element; element = elements[i++];)
Notice that in browser that would support querySelectorAll you can also do something like:
var elements = document.querySelectorAll("#my-form input[type=text][value='']")
And you will have in elements just the element that have an empty value attribute. Notice however that if the value is changed by the user, the attribute will be remain the same, so this code is only to filter by attribute not by the object’s property. Of course, you can also mix the two solution:
var elements = document.querySelectorAll("#my-form input[type=text]") for (var i = 0, element; element = elements[i++];)
You will basically save one check.