178

Consider this function:

function validate()
{
  var acc = document.getElementsByName('acc').value;
  var pass = document.getElementsByName('pass').value;

  alert (acc);
}

And this HTML part:

<table border="0" cellpadding="2" cellspacing="0" valign="top">
    <tr>
        <td class="td1">Account</td>
        <td class="td2"><input type="text" name="acc" /></td>
    </tr>
    <tr class="td1">
        <td>Password</td>
        <td class="td2"><input type="password" name="pass" /></td>
    </tr>
</table>
<div><button onClick="validate()" class="cupid-greenx">Login now</button></div>

The alert box is showing, but it shows "undefined".

Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
Juliver Galleto
  • 8,831
  • 27
  • 86
  • 164
  • 1
    If you can change it altogether, I would recommend adding a field "id" to your two input fields, and use `document.getElementById`, which returns exactly one value. – Odi Apr 24 '12 at 21:22
  • 4
    better still: `var inputs = document.getElementsByTagName('input')`, returns a nodelist, from which you can extract both elements like so: var pass = inputs.item('pass'). Just a tip, this can speed things up if you're dealing with a big DOM, as `getElementById` will search the entire tree each time, whereas a nodelist won't, so it's faster... – Elias Van Ootegem Apr 24 '12 at 21:34
  • Little cute code indeed XD – Guillermo Gutiérrez May 22 '14 at 20:30

8 Answers8

323

The reason you're seeing that error is because document.getElementsByName returns a NodeList of elements. And a NodeList of elements does not have a .value property.

Use this instead:

document.getElementsByName("acc")[0].value
jkeys
  • 3,803
  • 11
  • 39
  • 63
Aidanc
  • 6,921
  • 1
  • 26
  • 30
49

All Answers here seem to be outdated. Please use this now:

document.querySelector("[name='acc']");
document.querySelector("[name='pass']")
36

Note the plural in this method:

document.getElementsByName()

That returns an array of elements, so use [0] to get the first occurence, e.g.

document.getElementsByName()[0]
Ozzy
  • 8,244
  • 7
  • 55
  • 95
  • 8
    It's not an array, it's a NodeList :-) – Florian Margaine Apr 24 '12 at 21:23
  • 1
    @FlorianMargaine - Actually it's a [HTMLCollection](https://developer.mozilla.org/en/DOM/HTMLCollection) ;) – j08691 Apr 24 '12 at 21:26
  • 1
    @j08691 [nope](https://developer.mozilla.org/en/DOM/document.getElementsByName) :) but it can be easy to be confused :p – Florian Margaine Apr 24 '12 at 21:29
  • 2
    Whats the definition of an array and how is this different? A NodeList is just an object wrapped around an array of HTMLElements with a few convenience methods. Anyway, to put it in layman's terms for the OP, I said an array. – Ozzy Apr 24 '12 at 21:30
  • 2
    An array has a lot more methods than a NodeList. A NodeList takes some methods/properties from arrays such as the `length` property, but it's also missing *a lot* of methods, such as `map`, `forEach`, etc. Which explains why we need to use: `Array.prototype.forEach.call( NodeList, fn )`. – Florian Margaine Apr 24 '12 at 21:32
  • In basic terms, an array is a collection of elements, so it is not incorrect to call it an array. Its like if I were to call you a mammal rather than a human being; you are both, although human being describes you most accurately. – Ozzy Apr 24 '12 at 21:36
  • @FlorianMargaine - "document.getElementsByName() returns aHTMLCollection of all the elements with a given value for the name attribute." – j08691 Apr 24 '12 at 22:54
  • @j08691 uh, yeah. The [french version](https://developer.mozilla.org/fr/DOM/document.getElementsByName) says it returns a NodeList :o – Florian Margaine Apr 25 '12 at 06:44
  • @Ozzy: well, except an `array` in javascript is a specific kind of object, not just a concept. – Florian Margaine Apr 25 '12 at 06:44
16

You want this:

function validate() {
    var acc = document.getElementsByName('acc')[0].value;
    var pass = document.getElementsByName('pass')[0].value;

    alert (acc);
}
Elliot Bonneville
  • 51,872
  • 23
  • 96
  • 123
9

Method document.getElementsByName returns an array of elements. You should select first, for example.

document.getElementsByName('acc')[0].value
dalazx
  • 149
  • 3
6
document.getElementsByName("myInput")[0].value;
Sam Battat
  • 5,725
  • 1
  • 20
  • 29
2

Just for completeness so others reading this have a good idea of safety nets, especially with no guarantee to get the element you want, you could test for missing values, using null coalesce to set a default:

const accElements = document.getElementsByName('acc');
const accElement = accElements[0] ?? null; // Or some other value
if (!accElement) {
    // handle the problem
}

And use Optional chaining when it's connected objects (and not arrays/nodes being returned):

const acc = document.getElementById('acc')?.value ?? null; // Or some other value

Also, while the name attribute is sometimes all that is available, do try to use id where possible as they have more chance of being unique. Assuming that your desired element is in results index 0 ([0]) is usually safe, but better to check and be sure. For a few lines of code (with some logging perhaps) you save your end users the problems of things breaking.

James
  • 4,644
  • 5
  • 37
  • 48
0

If you have many input you can try this:

<input type="text" name="unitOfAttachService">
<input type="text" name="unitOfAttachService">
<input type="text" name="unitOfAttachService">

this line is used to get all values of the tag input

let unitOfAttachService =document.getElementsByName("unitOfAttachService");

this is how to get it out of the list and use

for (let k = 0; k < unitOfAttachService .length; k++) {
  unitOfAttachService[k].value;}
TRIPLE T
  • 1
  • 2