dev101
dev101

Reputation: 1369

javascript <form name="item"> and getElementsByTagName() error

I cannot explain why is this happening:

Uncaught TypeError: form_item.getElementsByTagName is not a function

Code Snippet:

var form_item = document.forms['item'];
var buttons_item = form_item.getElementsByTagName('button');
for (var i = 0; i < buttons_item.length; i++) {
	if (buttons_item[i].type === 'submit') {
		buttons_item[i].classList.add('someclass');
	}
}
<form name="item" action="">
    <button type="submit">Button</button>
</form>

If I change the form's name, it works without any errors.

What is wrong? Why? Thanks

Upvotes: 2

Views: 542

Answers (3)

Mohammad Kermani
Mohammad Kermani

Reputation: 5396

The querySelector in JavaScript works like what you may know in JQuery selctors.

MDN: Document.querySelector() Returns the first Element within the document (using depth-first pre-order traversal of the document's nodes|by first element in document markup and iterating through sequential nodes by order of amount of child nodes) that matches the specified group of selectors.

For your HTML markup you could use just use [name='item':

var form_item = document.querySelector('[name=item]');
var buttons_item = form_item.getElementsByTagName('button');
for (var i = 0; i < buttons_item.length; i++) {
  if (buttons_item[i].type === 'submit') {
    buttons_item[i].classList.add('someclass');
  }
}
.someclass {
  background: #6600ff;
  color: white;
}
<form name="item" action="">
  <button type="submit">Button</button>
</form>


The snippet above works as expected, but here is the question, why the item name was not working by the way you were going to access that!?

Because the item is a function for doctument.forms

W3S: item(index) Returns the element from the collection with the specified index (starts at 0).

You can easily try it, open your web developer console (like Chrome DevTools) and type in: document.forms.item(0), you will get the first form of the document


By the way, this function also can be helpful to understanding better how really forms work

function getFormByName(theName) {
    for (var i = 0; i < document.forms.length; i++) {
        var form_item = document.forms.item(i);
        if (form_item.name == theName) {
            return form_item;
        }
    }
    return false;
}

var form_item = getFormByName('item');
if (form_item) {
    var buttons_item = form_item.getElementsByTagName('button');
    for (var i = 0; i < buttons_item.length; i++) {
        if (buttons_item[i].type === 'submit') {
            buttons_item[i].classList.add('someclass');
        }

    }
}
.someclass{
   background:gold;
   color:red;
   border:none;
}
<form name="item" action="">
  <button type="submit">Button</button>
</form>

Upvotes: 1

Marco Salerno
Marco Salerno

Reputation: 5203

var form_item = document.querySelector('form[name=item]');
var buttons_item = form_item.getElementsByTagName('button');
for (var i = 0; i < buttons_item.length; i++) {
	if (buttons_item[i].type === 'submit') {
		buttons_item[i].classList.add('someclass');
	}
}
<form name="item" action="">
	<button type="submit">BUTTON</button>
</form>

You can try it inside your browser's console type and send those commands:

document.forms["item"]

-

document.forms.item

Those commands means the same thing and ask for the document.forms.item() function.


And that's the workaround you need:

document.querySelector('form[name=item]');

Upvotes: 2

SLaks
SLaks

Reputation: 887449

document.forms.item is a function that returns a form.

Your name conflicts with that.

Upvotes: 5

Related Questions