user1032531
user1032531

Reputation: 26281

Implications when an input has the same name as another input's ID

The following script surprised me. It produces the following results:

InternetExplore

aaa: undefined bbb: undefined ccc: value3 ddd: value4 eee: value5

FireFox and Chrome

aaa: bbb: ccc: value3 ddd: value4 eee: value5

Why when one input has the same ID as another input's name (or by reverse), the input doesn't have a value?

function testResults(form) {
  alert([
    "aaa: " + form.aaa.value,
    "bbb: " + form.bbb.value,
    "ccc: " + form.ccc.value,
    "ddd: " + form.ddd.value,
    "eee: " + form.eee.value
  ].join(',    '));
}
<form>
  <input type="text" name="aaa" id="bbb" value="value1" />
  <input type="text" name="bbb" id="aaa" value="value2" />
  <input type="text" name="ccc" id="ccc" value="value3" />
  <input type="text" name="ddd" value="value4" />
  <input type="text" id="eee" value="value5" />
  <input type="submit" onclick="testResults(this.form)"/>
</form>

Upvotes: 2

Views: 602

Answers (2)

Farzher
Farzher

Reputation: 14563

The DOM is weird...

But querySelector will let you get by name OR id. It's like the jQuery selector.

form.querySelector('[name=aaa]').value
form.querySelector('#aaa').value

The reason it doesn't have a value btw is because form.aaa tries to match by id or name and returns multiple elements. Trying to get the value of that returns "", or apparently undefined in IE

Upvotes: 2

Oriol
Oriol

Reputation: 288120

The algorithm used when you access a form element by name or ID is defined in the spec:

When a form element is indexed for named property retrieval, the user agent must run the following steps:

  1. Let candidates be a live RadioNodeList object containing all the listed elements whose form owner is the form element that have either an id attribute or a name attribute equal to name, with the exception of input elements whose type attribute is in the Image Button state, in tree order.

  2. If candidates is empty, let candidates be a live RadioNodeList object containing all the img elements that are descendants of the form element and that have either an id attribute or a name attribute equal to name, in tree order.

  3. If candidates is empty, name is the name of one of the entries in the form element's past names map: return the object associated with name in that map.

  4. If candidates contains more than one node, return candidates and abort these steps.

  5. Otherwise, candidates contains exactly one node. Add a mapping from name to the node in candidates in the form element's past names map, replacing the previous entry with the same name, if any.

  6. Return the node in candidates.

Specifically, the problem is that there are two candidates for form.aaa, so it returns a RadioNodeList collection (step 4):

form.aaa; // RadioNodeList [ <input#bbb>, <input#aaa> ]
form.aaa[0]; // <input#bbb>
form.aaa[1]; // <input#aaa>

For form.eee there is only one candidate, so it is returned instead (step 6):

$0.eee; // <input#eee>

Upvotes: 3

Related Questions