Assigning click event handler inside keyup event causes the click event to be fired multiple times

I am attempting to add an event handler to an anchor only when certain form fields are populated, like so:

$('#newName, #newFrom').keyup(function (e) {
    if ($('#newName').val() || $('#newFrom').val()) {
        $('#add-person').click(function (e) {
            //Handle event, includes adding a row to a table.
            $('this').off();
        });
    }
});

It seems like the first event is getting propagated to the second one since I end up with the same number of rows in my table as keys I have typed.

I've tried adding

    e.stopPropagation();

But with no success.

Answers 1

  • $('this').off(); should be $(this).off();
    also probably you'd better go using the input event instead of keyup. input event will trigger even if one pastes content into your fields.

    nevertheless I'd go the other way around:

    // (cache your selectors)
    var $newName = $("#newName"),
        $newFrom = $("#newFrom");
    
    // create a boolean flag
    var haveNewValue = false;
    
    // modify that flag on fields `input`
    $newName.add( $newFrom ).on("input", function() {
      haveNewValue = ($.trim($newName.val()) + $.trim($newFrom.val())).length > 0;
    });
    
    // than inside the click test your flag
    $('#add-person').click(function (e) {
      if(!haveNewValue) return; // exit function if no entered value.
    
      // do stuff like adding row to table
    });
    

    What was wrong:

    on every keyup you was assigning a new (therefore multiple) click event/s to the button, but the (corrected to:) $(this).off() was triggered only after an actual button click.

    Also a better way to use .on() and off.() (notice the difference in using the .click() method and the .on() method) is:

    function doCoffee() {
      alert("Bzzzzzzzz...BLURGGUZRGUZRGUZRG");
    }
    
    $("#doCoffeeButton").on("click", doCoffee); // Register "event" using .on()
    
    $("#bossAlertButton").click(function() {
       $("#doCoffeeButton").off("click");       // Turn off "event" using .off()
    });
    

Related Articles