tags:

views:

142

answers:

3

I am binding 3 events:

$("#form").bind('keyup change submit',function(event){ //do something alert("test alert"); });

In a form you can have text fields, dropdowns, checkboxes, etc....

From what I noticed, the "change" event does not get triggered with text fields until you click 'outside' of the text box. So, I use the "keyup" event, which works great for me.
And the "submit" event is self explanatory. (I'm basically saving myself from doing multiple selectors by binding these events.) And I may want to add more events later.

Here is my problem....

The popup alert will trigger 2x, when I make a change to a textbox. Not sure if that's because I am clicking the button on the popup that causes it, or if changing the value in the textbox can also trigger both the keyup & change events at the same time.

Either way, it's driving me nuts.

Any thoughts on improving this method, without having multiple selectors?

A: 

Why don't you set a Boolean flag somewhere outside of the callback functions (still in a shared scope of course). The first call will set the flag and execute, the others will see the flag and return. You can reset the flag when the user closes the alert box.

EDIT: Another option if you still want different elements to be able to issue these alerts is have the handler remove itself as an event listener. Then you could re register it when the alert box closes.

Ryan Lynch
A: 

The second alert is triggered by the first one. When the first alert pops up, the textfield lose the focus and the change event is triggered. If your real handler doesn't cause the textfield to lose the focus that shouldn't be a problem. However, you may want to ignore the change event in textfields because you're already using keyup to process those fields.
Using the flag idea from Ryan Lynch, you can do the following:

var target = null;
$("#form").bind('keyup change submit',function(event){
    if (event.type == 'keyup') {
        target = event.target;
    // a change event after one or more keyup events in the same element
    } else if (event.type == 'change' && target === event.target) {
        //do nothing
        return false;
    }
    // actual handler code
    alert(event.type) // test code
});

Tested on Firefox. I hope this helps.

Willington Vega
Surely `target === event.target` is always false, as `target` is undefined?
Eric
`target` is `null` until a keyup event is triggered. When the user is typing, multiple keyup events are triggered thus setting `target` to the current element. When the change event is triggered on that element (after it lose focus) `target === event.target` is true.
Willington Vega
+1  A: 

Edit: I just saw your note on "not having multiple selectors." The following could be chained if desired, if that would somehow fit the bill.

To be most efficient with memory, I would break that up into a couple of statements.

//Your function
var handler = function(e) {  alert('blah'); };

$('#form input[type=text], #form textarea').keyup(handler);
$('#form select, #form checkbox, #form radio').change(handler);
$('#form').submit(handler);

This is nice because elements only trigger one event, and it's the one that can help you.

On a side note, if you're expecting IE 6 support, the change event doesn't trigger until the checkbox/radio/select blurs, so you may want to handle those differently (click still works nicely for checkbox/radio).

jarcoal
the OP should *really* split it up, instead of convoluting a single monolithic doitall through if-soup.
just somebody