I have an array of all the forms
in my page. I want to iterate through all the forms, and find the buttons in them. How can I achieve this in Javascript alone, without any libraries?
Here's my JS code :
var forms = document.querySelectorAll('form');
for(var i = 0; i < forms.length; i++;){
var form = forms[i];
form.addEventListener('submit', validateForm);
}
function validateForm(e){
e.preventDefault();
var button = ?; // I want to get the button that is a child of this form
}
I know that I can use this to get all the buttons that are children of a form :
var buttons = document.querySelectorAll('form button');
But how can I get just one button that is a children of this form?
I've seen this question asked multiple times, but it was always to find the children of a parent that was known, with a specific id
or something like that. I have no idea how many forms there will be in the page, and I have no control on wether or not they have unique id
or anything else that could be used to differentiate them when using querySelectorAll()
.
Is it possible to achieve what I want?
I'm looking for the pure JS alternative to this in jQuery :
var $form = $('form');
var $childButton = $form.find('button');
I have an array of all the forms
in my page. I want to iterate through all the forms, and find the buttons in them. How can I achieve this in Javascript alone, without any libraries?
Here's my JS code :
var forms = document.querySelectorAll('form');
for(var i = 0; i < forms.length; i++;){
var form = forms[i];
form.addEventListener('submit', validateForm);
}
function validateForm(e){
e.preventDefault();
var button = ?; // I want to get the button that is a child of this form
}
I know that I can use this to get all the buttons that are children of a form :
var buttons = document.querySelectorAll('form button');
But how can I get just one button that is a children of this form?
I've seen this question asked multiple times, but it was always to find the children of a parent that was known, with a specific id
or something like that. I have no idea how many forms there will be in the page, and I have no control on wether or not they have unique id
or anything else that could be used to differentiate them when using querySelectorAll()
.
Is it possible to achieve what I want?
I'm looking for the pure JS alternative to this in jQuery :
var $form = $('form');
var $childButton = $form.find('button');
Share
Improve this question
asked Jun 2, 2016 at 0:58
DrownDrown
5,9821 gold badge32 silver badges49 bronze badges
3 Answers
Reset to default 6Element has equivalent versions of querySelector/All and so can be called from elements as well as document. So if you are looking for a button inside a form element you can just call querySelector from the form element
var form = document.querySelector("#SomeForm");
//Will find the first button in the form
var someBtn = form.querySelector("button");
//Will find all buttons in the form.
var someBtns = form.querySelectorAll("button");
Demo
let forms = document.querySelectorAll("form");
[].forEach.call(forms,form=>{
form.querySelector("button").innerText += " - Modified";
});
<form>
<button>A button</button><br>
<input><input>
</form>
<form><br><br>
<button>B button</button><br>
<input><input><br>
<button>C button</button>
</form><br><br>
<form>
<button>D button</button><br>
<input><input>
</form>
If you want to select the first button
descendant, you can use querySelector
.
But if you want to make sure it's a child, then you can use [].find
:
[].find.call(form.children, function(child) {
return child.tagName.toLowerCase() === 'button';
});
Alternatively, some browsers support the :scope
psudo-class:
form.querySelector(":scope > button");
Hopefully it won't be removed together with scoped stylesheets and @scope
at-rule.
Your question isn't really clear. There is a document.forms collection that is all the forms in a document in DOM order, so:
var firstForm = document.forms[0];
will get the first form. If your buttons have names, you can get the button with name "Fred" in the first form using:
var fred = document.forms[0].Fred;
Or the first button in the first form with:
var firstButton = document.forms[0].querySelector('button');
Or all the buttons in the first form with:
var firstButton = document.forms[0].querySelectorAll('button');
and so on. Note that form controls can be associated with a form using the form attribute, but not be inside the form. E.g.
<form id="foo">
<!-- stuff in the form -->
</form>
<button type="submit" for="foo">Submit the form</button>
In this case the querySelector syntax fails but form property access doesn't, so you might need to loop over the form's elements collection:
for var i=0, firstButton; i<firstForm.elements.length; i++) {
if (firstForm.elements[i].tagName.toLowerCase() == 'button') {
// This is the first button associated with the form,
// even if not actually in the form
}
}
So if you want to cover every case, your code needs to be very generic. But if you narrow down the likely scenarios, the code is very much simpler.