Search code examples
javascriptjqueryclassevent-handlingstoppropagation

jQuery class event handlers - how to disable for one element in class


I have an event handler attached to a class, as so:

$('#container').on('click', '.myClass', function (e) {...

Within this handler I want to attach a different click handler to the element that has been clicked. When the temporary handler has been clicked, I want to re-enable the original handler.

What I'm trying to do (as shown in this fiddle) is allow a section of text to be clicked, change that to an input text box, and then submit the change to recreate the text.

I've tried the following without success as found at the fiddle:

$('#container').on('click', '.submit', function (e) {
    var $this = $(this),
        new_text = $this.prev().val();
    e.stopPropagation();
    $this.parent().off('click.temp').html(new_text);                    
});

$('#container').on('click', '.test', function (e) {
    var $this = $(this);
    $this.html("<input type='text' value='" + $this.text() + "'/><input class='submit' value='Submit' type='submit'>");
    $this.on('click.temp', function (e) {
        e.stopPropagation();
    });
});

Using an .off() doesn't seem to cancel the original handler on the class because it is attached to the class not the element.

I think I've partly answered my question with e.stopPropagation(), but it's still not quite working and I'm not convinced I'm going about this the best way :)

Note: This post relates to the idea but does not use this.


Solution

  • Rather than adding and removing handlers for the inputs on the fly, I'd stick with delegated event handlers like you're already doing in the click handler that creates the inputs:

    $('#container').on('click', '.test', function (e) {
        var $this = $(this);
        $this.removeClass("test")
             .html("<input type='text' value='" + $this.text() + "'/><input id='me' value='Submit' type='button'>");
    });
    
    $('#container').on('click', 'input[type="button"]', function (e) {
        var $this = $(this),
            new_text = $this.prev().val();
        $this.parent().addClass("test")
                      .html(new_text);
    });
    

    On click of a '.test' div replace its contents with inputs like you were doing, but also remove the "test" class so that further clicks on the div won't do anything (for the moment).

    On click of a submit button change the div back to just show the text, and add the class back again so that the previous click handler takes effect again.

    Note: I've changed your buttons from type="submit" to type="button" because they're not actually used to submit a form.

    Demo: http://jsfiddle.net/4vmQ4/5/