216

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>
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
user377419
  • 4,681
  • 13
  • 42
  • 56
  • 2
    What do you mean by "value of a form in HTML code" exactly? – Pekka Aug 23 '10 at 11:24
  • 35
    question is quite clear – laurentngu Apr 15 '18 at 20:33
  • 2
    @laurentngu the question is does he mean "a value *of* an HTML form", meaning one value out *of* the many values, or does he mean the "*value* of the entire HTML form", meaning all of the values in one big "serialized" value – B''H Bi'ezras -- Boruch Hashem May 19 '20 at 08:17
  • 3
    The question is clear... but clearly it doesn't make a lot of sense to pass the value of a form. – Matthew Jul 16 '20 at 13:17
  • 1
    Node that while in 2010 the answer here was fairly involved, ever since Object.entries landed in JS, https://stackoverflow.com/a/66407161/740553 has been the real answer to the "getting all form values" interpretation of this question. – Mike 'Pomax' Kamermans Oct 26 '21 at 16:30

19 Answers19

158

HTML:

<input type="text" name="name" id="uniqueID" value="value" />

JS:

var nameValue = document.getElementById("uniqueID").value;
user406632
  • 1,735
  • 1
  • 12
  • 8
  • 9
    @shorty876: Did you test it yourself? o_0 That would be a pretty good way of determining whether or not you did it right. – Jeff Rupert Aug 23 '10 at 11:46
  • 1
    Yeah, but it just returns a true/false and im not sure how to determine if the function was even called. Thus you can help. – user377419 Aug 23 '10 at 13:00
  • I tried this out, but `nameValue` is the default value and not what the user entered. – James T. Dec 12 '17 at 20:54
  • 1
    why name="name", and what if it doesnt have an ID at all? – B''H Bi'ezras -- Boruch Hashem May 19 '20 at 08:19
  • @bluejayke there are other javascript methods that get data from HTML tags, such as `getElementsByClassName`. "name" is just a generic attribute placeholder in this case. – Anonymous Nov 23 '20 at 12:33
  • `name="first name"` is the name of the data that was taken from the form and not the id of the html tag. Kind of like in json file `{"first name" : "Mike"}` – Hank W May 22 '21 at 13:01
151

If you want to retrieve the form values (such as those that would be sent using an HTTP POST) you can use FormData class:

JavaScript

document.getElementById("myForm").addEventListener("submit", function (e) {
  e.preventDefault();

  var formData = new FormData(form);
  // output as an object
  console.log(Object.fromEntries(formData));

  // ...or iterate through the name-value pairs
  for (var pair of formData.entries()) {
    console.log(pair[0] + ": " + pair[1]);
  }
});

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()
Kevin Farrugia
  • 6,431
  • 4
  • 38
  • 61
  • 16
    Your first example `FormData` itself doesn't do anything.. you still need to get the values from the form. – putvande Dec 21 '16 at 12:39
  • 2
    I believe that is incorrect. If when initialising the FormData you specify a form element then it will correctly retrieve the values. http://codepen.io/kevinfarrugia/pen/Wommgd – Kevin Farrugia Dec 21 '16 at 13:34
  • 2
    The FormData object is not itself the values though. You still need to call and iterate through `FormData.entries()` in order to retrieve the values. Additionally, `FormData.entries()` is not available in Safari, Explorer, or Edge. https://developer.mozilla.org/en-US/docs/Web/API/FormData – dave Oct 11 '17 at 21:08
  • 2
    Correct in regards to browser compatibility, however there are [polyfills](https://www.npmjs.com/package/formdata-polyfill). Regarding iterating through `formData.entries()`, it depends what you are looking for. If you are looking for the value of a single field you could use `formData.get(name)`. Reference: [get()](https://developer.mozilla.org/en-US/docs/Web/API/FormData/get). – Kevin Farrugia Oct 12 '17 at 07:02
  • 2
    Yeah I can't get `FormData` to output anything on Chrome. – Atav32 Mar 26 '18 at 19:11
  • To iterate through `.entries()` in ES5 you can do `var entries = formData.entries(); var iter; while(!(iter = entries.next()).done){ console.log(iter.value) }` – Matt Mc May 25 '20 at 03:19
  • 8
    This is the answer I came here for. The question of the post is 'Getting HTML form values'- values being plural. The current top answer only grabs a single input value, I want to know how to grab the entire form and then parse out the values. This should be the top answer. – kdub1312 Jun 30 '21 at 21:29
  • 1
    IMPORTANT: the inputs need to have the "name" attribute to show up in the FormData entries. Setting an id is not enough. – Mr. Developerdude Jun 01 '23 at 11:56
124

I think this is the most elegant solution

function handleSubmit(e) {
  e.preventDefault();
  const formData = new FormData(e.target);
  const formProps = Object.fromEntries(formData);
}
DedaDev
  • 4,441
  • 2
  • 21
  • 28
  • 1
    how is the function called from HTML? – Radek Aug 17 '21 at 19:42
  • 4
    @Radek Example: `const loginForm = document.getElementById("login-form");` `loginForm.addEventListener("submit", handleSubmit);` – David Michael Gregg Aug 20 '21 at 17:35
  • 3
    Worked like a charm , you nailed it! @DedaDev – projektorius96 Oct 03 '21 at 15:38
  • 3
    This won't work for forms with array fields. Imagine multiple `` this will just capture the last value. – Jon Catmull Jan 25 '22 at 10:21
  • 1
    That is not even a thing in HTML @JonCatmull – DedaDev Jan 27 '22 at 06:10
  • 3
    @DedaDev depends what you mean by a "thing" it is valid to have inputs with the same name e.g. for checkboxes and I would expect these to be collected as an array instead of just returning the last field with that name. I think perhaps the example I posted using `[]` is more of an old PHP convention but doesn't really change the point. https://stackoverflow.com/questions/452066/html-form-with-multiple-hidden-control-elements-of-the-same-name – Jon Catmull Jan 27 '22 at 14:17
48

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.

Kaspar Lee
  • 5,446
  • 4
  • 31
  • 54
  • 14
    Just a warning, if anyone wants to get the selected values of other types of inputs such as radio buttons or checkboxes, this won't do what you want. – Sean Nov 23 '16 at 05:59
  • I had to change `var obj = {};` to `var obj = [];`. – Daniel Williams Jul 01 '19 at 20:04
  • @Sean why would it not work for radio buttons? They appear under the elements property also – B''H Bi'ezras -- Boruch Hashem May 19 '20 at 07:31
  • 2
    @bluejayke The code will cycle through all of the radio button inputs, and will save the 'value' of the LAST radio button against `obj`, regardless of which one is selected. The issue is demonstrated here (choose 'Option 1') https://www.w3schools.com/code/tryit.asp?filename=GEZXJXBBI7AW – Sean May 21 '20 at 03:52
32

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);
Kaspar Lee
  • 5,446
  • 4
  • 31
  • 54
Codeacula
  • 2,329
  • 25
  • 30
  • 1
    Why the shorter method was not mentioned first? =-D – Klesun Feb 17 '20 at 19:02
  • 3
    @ArturKlesun I would guess it's because at the time a decade ago I started to type the answer, the OP hadn't updated, so I wrote the for loop to handle most situations. I think back then I was also ensuring browser compatibility with IE7 because we didn't have the far better landscape we have today. – Codeacula Feb 18 '20 at 21:49
25

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

jhaavist
  • 681
  • 7
  • 11
16

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;
Klesun
  • 12,280
  • 5
  • 59
  • 52
  • I should note that, the element name is case sensitive. form.elements['cardtype'].value and form.elements['CardType'].value aren't the same. – Sinan ILYAS Apr 11 '21 at 10:24
8

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')

smartexpert
  • 2,625
  • 3
  • 24
  • 41
5

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.

Rusca8
  • 533
  • 4
  • 11
3

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>
Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
3

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.

Ulvi
  • 965
  • 12
  • 31
3

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>
BlakeWebb
  • 479
  • 5
  • 11
3
<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"}
    */
}
2

Several easy-to-use form serializers with good documentation.

In order of Github stars,

  1. jquery.serializeJSON

  2. jquery-serialize-object

  3. form2js

  4. form-serialize

Atav32
  • 1,788
  • 3
  • 23
  • 33
2

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)
}
1

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>
1

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"] }

Jon Catmull
  • 11,873
  • 5
  • 19
  • 17
0
<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>
-1
<input type="text" id="note_text" />

let value = document.getElementById("note_text").value;
Randhawa
  • 226
  • 1
  • 15