Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery. Do not fire one event if already fired another

I have a code like this:

$('#foo').on('click', function(e) {
   //do something
});

$('form input').on('change', function(e) {
  //do some other things
));

First and second events do actually the same things with the same input field, but in different way. The problem is, that when I click the #foo element - form change element fires as well. I need form change to fire always when the content of input is changing, but not when #foo element is clicked.

That's the question )). How to do this?

UPD: here is the code on jsfiddle: http://jsfiddle.net/QhXyj/1/

like image 607
Taras Bulgakov Avatar asked Nov 11 '12 10:11

Taras Bulgakov


2 Answers

What happens is that onChange fires when the focus leaves the #input. In your case, this coincides with clicking on the button. Try pressing Tab, THEN clicking on the button.

To handle this particular case, one solution is to delay the call to the change event enough check if the button got clicked in the meantime. In practice 100 milisecond worked. Here's the code:

$().ready(function() {

    var stopTheChangeBecauseTheButtonWasClicked = false;
    $('#button').on('click', function(e) {
        stopTheChangeBecauseTheButtonWasClicked = true;
        $('#wtf').html("I don't need to change #input in this case");
    });

    $('#input').on('change', function(e) {
        var self = this;
        setTimeout(function doTheChange() {
            if (!stopTheChangeBecauseTheButtonWasClicked) {
                $(self).val($(self).val() + ' - changed!');
            } else {
                stopTheChangeBecauseTheButtonWasClicked = false;
            }
        }, 100);
    });
});

And the fiddle - http://jsfiddle.net/dandv/QhXyj/11/

like image 81
Dan Dascalescu Avatar answered Oct 10 '22 09:10

Dan Dascalescu


It's only natural that a change event on a blurred element fires before the clicked element is focused. If you don't want to use a timeout ("do something X ms after the input was changed unless in between a button was clicked", as proposed by Dan) - and timeouts are ugly - you only could go doing those actions twice. After the input is changed, save its state and do something. If then - somewhen later - the button is clicked, retrieve the saved state and do the something similar. I guess this is what you actually wanted for your UI behaviour, not all users are that fast. If one leaves the input (e.g. by pressing Tab), and then later activates the button "independently", do you really want to execute both actions?

var inputval = null, changedval = null;

$('form input').on('change', function(e) {
    inputval = this.value;
    // do some things with it and save them to
    changedval = …
    // you might use the value property of the input itself
));

$('#foo').on('click', function(e) {
    // do something with inputval
});

$('form …').on('any other action') {
    // you might want to invalidate the cache:
    inputval = changedval;
    // so that from now on a click operates with the new value
});
like image 41
Bergi Avatar answered Oct 10 '22 10:10

Bergi