Search code examples
javascriptjquerybindlive

JQuery function, wrapping and live binding


I've written a nice function to wrap an input with increment/decrement buttons:

$.fn.qDecInc = function(){
return this.wrap('<span id="qButtons" />').after($('<span/>', { class: 'qIncButton' }).bind('click', function() {
    var ov = 0;
    if (isNaN($(this).val())){
        ov = 0;
    } else {
        ov = $(this).val();
    }
    if (ov < 99){
        var nv = parseFloat(ov) + 1;
        $(this).val(nv);
        $(this).keyup();
        $(this).change();
    }
}), $('<span/>', { class: 'qDecButton', style: 'top: 11px;' }).bind('click', function() {
    var ov = 0;
    if (isNaN($(this).val())){
        ov = 0;
    } else {
        ov = $(this).val();
    }
    if (ov > 0){
        var nv = parseFloat(ov) - 1;
        $(this).val(nv);
        $(this).keyup();
        $(this).change();
    }
}));
}

Values get updated, but the inputs not. I've tried

$(this).live("change");

and even

$("body").delegate($(this), "change");

to no avail. What did I miss?

http://jsfiddle.net/MVxsA/1/ - here's a jsfiddle for your convenience.


Solution

  • Two issues

    1. in this context, you should use .bind('click', function() {...}) instead of live(). Or you can use the convenient shortcut method .click(function() {...}). The function live() is used when elements will be added to the dom later, and you want jQuery to automatically attach listeners to the new elements at that time. For this reason, live() also requires a selector (which your example omits).

    2. When inside an event handler, this refers to the element on which the listener was fired. So in this case, this is the qIncButton or qDecButton, not the element to which the plugin is applied.

    Here's how these issues can be corrected:

    $.fn.qDecInc = function(){
        var self = this;
        return self.wrap('<span id="qButtons" />').after($('<span/>', { class: 'qIncButton' }).click(function() {
            console.log("up");
            var ov = 0;
            if (isNaN($(self).val())){
                ov = 0;
            } else {
                ov = $(self).val();
            }
            if (ov < 99){
                var nv = parseFloat(ov) + 1;
                $(self).val(nv);
                $(self).keyup();
                $('body').change();
            }
        }), $('<span/>', { class: 'qDecButton', style: 'top: 11px;' }).click(function() {
            console.log("down");
            var ov = 0;
            if (isNaN($(self).val())){
                ov = 0;
            } else {
                ov = $(self).val();
            }
            if (ov > 0){
                var nv = parseFloat(ov) - 1;
                $(self).val(nv);
                $(self).keyup();
                $(self).change();
            }
        }));
    }
    

    Your updated jsFiddle is here