Reputation: 892
I have to prevent empty search submit on search forms. Forms does not have submit buttons, so I have to prevent the enter.
The html code:
Form 1
<form method="get" class="search-form" id="searchform" action="http://example.com" >
<input class="text" name="s" id="s" type="text" />
</form>
Form 2
<form action="http://example.com" class="search-form" method="get">
<input type="text" name="s" class="text">
</form>
The Javascript code
// Im sure this funcions returns the 2 different forms,
var searchForms = getElementsByClass('search-form');
for(i in searchForms)
{
if (searchForms[i].addEventListener)
{
searchForms[i].addEventListener("submit", function(e)
{
preventSubmit(e); // no problem here
console.log(i) // ALWAYS LOGS 1
});
} //I also implemented the ie code, but not necessary here, is the same as above for addEventListener
}
Every time I submit any form, writes 1 in the console, any idea?
Upvotes: 0
Views: 1678
Reputation: 19037
This is happening because of closure pls see similar link
Jquery dynamic buttons dialog for in loop doesn't populate function
Upvotes: 0
Reputation: 47099
You will need a closure:
var searchForms = getElementsByClass('search-form');
for(i in searchForms)
{
if (searchForms[i].addEventListener)
{
(function(i) { // Closure start <-- We make our own static variable i
searchForms[i].addEventListener("submit", function(e)
{
preventSubmit(e); // no problem here
console.log(i)
});
})(i); // Closure end.
}
}
It's because after your loop (for i in searchForms
) i
will be the last value (===1
). You will need to make a closure to have a static value of i
.
See more about closures here:
How do JavaScript closures work?
Upvotes: 4
Reputation: 34556
The callback is not executed until submit - by which time the value of i
is 1. A closure, in the form of an immediately-executing function, allows us to capture the varying value of i
and pass a copy of it in to our function.
Also
1) except in certain situations, generally avoid for-in
loops over arrays. Use traditional for
loops. If you were to use your present for-in
having selected the forms via the ECMA5 querySelectorAll()
method, for example, you would get unexpected results (four iterations of the loop, not two)
2) you are needlessly re-assessing which event registration mechanism to use for each iteration of the loop. Decide this once, outside.
//get forms
var searchForms = getElementsByClass('.search-form');
//initialise event registration depending on browser
var addEvent = window.addEventListener ? function(el, evt, func, bubble) {
el.addEventListener(evt, func, bubble);
} : function(el, evt, func) {
el.attachEvent('on'+evt, func);
};
//bind submit events
for (var i=0, len=searchForms.length; i<len; i++) {
(function(i) {
addEvent(searchForms[i], "submit", function(evt) { alert(i); preventSubmit(evt); }, false);
})(i);
}
Upvotes: 1