How an I get all form elements (input, textarea & select) with jQuery?
Asked Answered
I

15

131

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:

$("form").each(function(){
    let $inputs = $("input, textarea, select", this);
});
Impercipient answered 12/10, 2012 at 15:41 Comment(0)
P
213

Edit: As pointed out in comments (Mario Awad & Brock Hensley), use .find to get the children

$("form").each(function(){
    $(this).find(':input') //<-- Should return all input elements in that specific form.
});

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('<br />'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="A" style="display: none;">
    <input type="text" />
    <button>Submit</button>
</form>
<form id="B" style="display: none;">
    <select><option>A</option></select>
    <button>Submit</button>
</form>

<table bgcolor="white" cellpadding="12" border="1" style="display: none;">
<tr><td colspan="2"><center><h1><i><b>Login
Area</b></i></h1></center></td></tr>
<tr><td><h1><i><b>UserID:</b></i></h1></td><td><form id="login" name="login" method="post"><input
name="id" type="text"></td></tr>
<tr><td><h1><i><b>Password:</b></i></h1></td><td><input name="pass"
type="password"></td></tr>
<tr><td><center><input type="button" value="Login"
onClick="pasuser(this.form)"></center></td><td><center><br /><input
type="Reset"></form></td></tr></table></center>
<div id="results"></div>

May be :input selector is what you want

$("form").each(function(){ $(':input', this)//<-- Should return all input elements in that specific form. });

As pointed out in docs

To achieve the best performance when using :input to select elements, first select the elements using a pure CSS selector, then use .filter(":input").

You can use like below,

$("form").each(function(){
    $(this).filter(':input') //<-- Should return all input elements in that specific form.
});

Pontificate answered 12/10, 2012 at 15:43 Comment(7)
Thanks although after reading: api.jquery.com/input-selector performance being an issue I may as well list them. Good to know its possible thoughImpercipient
Is it just me or does this not work for select? EDIT: nevermind, works with select if I use find(':input')Admix
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.Tandie
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?Idoux
@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.Pontificate
In later versions of jQuery you should be able to use serializeArray() to get the names and values of the form elements like so: var formElementNames = $("#form-identifier").serializeArray(); With this, you could identify elements by their names. Not sure about the performance of this method however.Afra
Did jquery break something? I get VM364:1 Uncaught TypeError: $(...).each is not a functionValorie
S
64

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());
    }
);
Shortlived answered 19/9, 2013 at 9:50 Comment(2)
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. ?Airburst
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"Virile
C
17

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.

Collyrium answered 12/10, 2012 at 15:44 Comment(0)
B
11

JQuery serialize function makes it pretty easy to get all form elements.

Demo: http://jsfiddle.net/55xnJ/2/

$("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.

Bourguiba answered 22/4, 2019 at 9:25 Comment(1)
Use jQuery's serializeArray() instead. Saves the split(). $("form").serializeArray(); //get all form elements at once Hustings
H
8

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.
});
Hawken answered 9/3, 2014 at 23:45 Comment(1)
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.Annadiane
V
8

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.

enter image description here

$( 'body' ).on( 'mouseover', 'input, textarea, select, button, a', function() {
    var $tag = $( this );
    var $form = $tag.closest( 'form' );
    var title = this.title;
    var id = this.id;
    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 );
    } )
} );
Vaclav answered 26/7, 2015 at 15:43 Comment(1)
Great function! ThanksMoltke
M
7

This is my favorite function and it works like a charm for me!

It returns an object with all for input, select and textarea data.

And it's trying to getting objects name by look for elements name else Id else class.

var form_data = get_form_data();
console.log(form_data);

Function:

function get_form_data(element){
    element = element || '';
    var all_page_data = {};
    var all_forms_data_temp = {};
    if(!element){
        element = 'body';
    }

    if($(element)[0] == undefined){
        return null;
    }

    $(element).find('input,select,textarea').each(function(i){
        all_forms_data_temp[i] = $(this);
    });

    $.each(all_forms_data_temp,function(){
        var input = $(this);
        var element_name;
        var element_value;

        if((input.attr('type') == 'submit') || (input.attr('type') == 'button')){
            return true;
        }

        if((input.attr('name') !== undefined) && (input.attr('name') != '')){
            element_name = input.attr('name').trim();
        } else if((input.attr('id') !== undefined) && (input.attr('id') != '')){
            element_name = input.attr('id').trim();
        } else if((input.attr('class') !== undefined) && (input.attr('class') != '')){
            element_name = input.attr('class').trim();
        }

        if(input.val() !== undefined){
            if(input.attr('type') == 'checkbox'){
                element_value = input.parent().find('input[name="'+element_name+'"]:checked').val();
            } else if((input.attr('type') == 'radio')){
                element_value = $('input[name="'+element_name+'"]:checked',element).val();
            } else {
                element_value = input.val();
            }
        } else if(input.text() != undefined){
            element_value = input.text();
        }

        if(element_value === undefined){
            element_value = '';
        }

        if(element_name !== undefined){
            var element_array = new Array();
            if(element_name.indexOf(' ') !== -1){
                element_array = element_name.split(/(\s+)/);
            } else {
                element_array.push(element_name);
            }

            $.each(element_array,function(index, name){
                name = name.trim();
                if(name != ''){
                    all_page_data[name] = element_value;
                }
            });
        }
    });
    return all_page_data;
}
Moltke answered 10/6, 2017 at 21:10 Comment(2)
Nice but there is a subtle bug in "Element_Value = jQuery('input[name="'+Element_Name+'"]:checked').val();". Element_Name might actually be the node id or class, in which case it won't find the element.Ceremonial
Correct, I have now fixed it!Moltke
P
4
var $form_elements = $("#form_id").find(":input");

All the elements including the submit-button are now in the variable $form_elements.

Planetstruck answered 29/6, 2013 at 13:17 Comment(1)
How do you access them?Avail
S
3

Just to add another way:

$('form[name=' + formName + ']').find(':input')
Sferics answered 11/5, 2015 at 13:9 Comment(0)
G
2

Try this function

function fieldsValidations(element) {
    var isFilled = true;
    var fields = $("#"+element)
        .find("select, textarea, input").serializeArray();

    $.each(fields, function(i, field) {
        if (!field.value){
            isFilled = false;
            return false;
        }
    });
    return isFilled;
}

And use it as

$("#submit").click(function () {

    if(fieldsValidations('initiate')){
        $("#submit").html("<i class=\"fas fa-circle-notch fa-spin\"></i>");
    }
});

Enjoy :)

Groundwork answered 15/10, 2019 at 18:12 Comment(0)
S
2

I used this way to get all input fields from a certain form:

$("#myForm").find("input").each(function() {
   // your stuff goes here
});

Or for the case here:

$("#myForm").find("select, textarea, input").each(function() {
   // your stuff goes here
});
Stebbins answered 16/11, 2021 at 10:31 Comment(0)
A
1

Years later…

const formElements = Object.entries($('form').get(0).elements)
    .reduce((arr, [_, el]) => 
        el.name 
            ? Object.assign(arr, { [el.name]: el.value }) 
            : arr, 
        {}
    );

The result is a simple key:value list of all form elements with a non-empty name.

For vanilla JS, replace $('form').get(0) with simple document.querySelector('form').

Annadiane answered 4/3, 2023 at 17:12 Comment(0)
W
0

Try something like this:

<form action="/" id="searchForm">
<input type="text" name="s" placeholder="Search...">
<input type="submit" value="Search">
</form>
<!-- the result of the search will be rendered inside this div -->
<div id="result"></div>

<script>
// Attach a submit handler to the form
$( "#searchForm" ).submit(function( event ) {

  // Stop form from submitting normally
event.preventDefault();

// Get some values from elements on the page:
var $form = $( this ),
term = $form.find( "input[name='s']" ).val(),
url = $form.attr( "action" );

// Send the data using post
var posting = $.post( url, { s: term } );

// Put the results in a div
posting.done(function( data ) {
  var content = $( data ).find( "#content" );
  $( "#result" ).empty().append( content );
    });
  });
</script>

Note the use of input[]

Wegner answered 29/10, 2018 at 3:41 Comment(1)
this doesn't seem to get textareas or selectsHannah
P
0

all inputs:

var inputs = $("#formId :input");

all buttons

var button = $("#formId :button")
Poteet answered 11/11, 2018 at 20:35 Comment(0)
S
0

const allFormElements = myForm.elements

just use the elements property for the form and no jquery needed.

if you are looking for all elements anywhere on the page:

html control elements must be one of the following: button,fieldset,input,object,output,select,textarea

so you can use JavaScript's native querySelectorAll

// use query selector instead
const nodes = document.querySelectorAll(
  ":where(button,fieldset,input,object,output,select,textarea)"
);
console.log({ nodes });
<div>
  <input type="text" id="name" name="name" value="bob">
</div>
<div>
  <textarea name="textarea" rows="10" cols="50">Write something here</textarea>
</div>
Seraglio answered 1/5, 2023 at 18:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.