0

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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Juan Jo
  • 882
  • 2
  • 8
  • 17
  • 2
    So many duplicates out there, like [this one](http://stackoverflow.com/questions/6487366/how-to-generate-event-handlers-with-loop-in-javascript). As a side note, don't use `for-in` when you only want sequential numeric iteration. It can cause problems. –  Jul 06 '12 at 18:07
  • preventSubmit(e); console.log(this) // will give you the correct form – SMathew Jul 06 '12 at 18:07
  • `i` is a reference to the index, not to the element. –  Jul 06 '12 at 18:22
  • Ever seen the show "News Radio"? –  Jul 06 '12 at 18:26
  • It was a show in the late 90's in the USA. Normally I hate sitcoms, especially ones with laugh-tracks, but I thought this one was very good. It had Phil Hartman *(from SNL)* until he died. Anyway, there was a "SMatthew" episode, so I thought maybe your username was a reference. –  Jul 06 '12 at 18:34

3 Answers3

4

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?

Community
  • 1
  • 1
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
1

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);
}
Mitya
  • 33,629
  • 9
  • 60
  • 107
0

This is happening because of closure pls see similar link

Jquery dynamic buttons dialog for in loop doesn't populate function

Community
  • 1
  • 1
Ajay Beniwal
  • 18,857
  • 9
  • 81
  • 99