Question

Here is jQuery widget code:

(function($){
    var _this,ele,parent;
    $.widget('test.talkWidget',{
        options:{
            a:'',
            b:''
        },
        destroy: function()
        {
            alert("asas");
            this.element
            .remove( ".talk" )
            .text( "" );
             $.Widget.prototype.destroy.call(this);
        },        
        _createTalkBox:function(){
    ele.find(".talk").prepend("<h1>talk box added</h1>");

        },
        _addReply:function(){alert("reply added");            
        },
        _attachEvent:function(){
            ele.on('keypress','textarea',function(e){
                if(e.keyCode===13){
                    alert($(this).val());_this._addReply();
                }
            });
            ele.on('click','.accept-check-off',function(e){                
                $(this).closest(".media").removeClass("accept-check-off accept-check-on");
                $(this).addClass("accept-check-on");
            });
            ele.on('click','.accept-check-on',function(e){
                $(this).closest(".media").removeClass("accept-check-off accept-check-on");
                $(this).addClass("accept-check-off");
            });            
        },
        _init:function(){
            ele=this.element;
            _this=this;
            parent=$("<div/>").addClass("talk").append("<br/><textarea class='form-control' rows='3'></textarea>");
            ele.html(parent);
            this._createTalkBox();
            this._attachEvent();
        }
    });
})(jQuery);

Here i am calling this widget:

<div id="target"></div>

<button>Show Widget</button>
<button id="b2">Show normal Text</button>

Problem is 'Reply Added' is shown as many times as i click 'Show Widget' button. Actually it should be shown only as many times as I press ENTER key inside Teaxtarea . I think widget is not destroying itself properly.

Check jsFiddle

Was it helpful?

Solution

The widget is not destroying because there is no call to the widget factory destroy() function.

In your jsFiddle, each time you click on the "Show Widget" button, you :

  • first remove the div #target content
  • then call the widget with no param.

Calling the widget with no params multiple times result in :

  • first time : call the factory create() function (which internally call the user defined _create() function, but you don't have some), then call the factory init() function (which internally call the user defined _init() function)
  • all other times : only call the init() function

The problem is that you are binding events in the _init() function, so new events are binded each time you call the plugin, that is to say each time you click on your buttons. Plus you bind a click event (to call your plugin) using button selector, so the event is binded on the 2 buttons.

You should define a _create() function which will be called only once, to define actions needing to be done only once, such as event binding.

Have a look in this jsFiddle, it should fit your needs. I simplified a little your code and add some explanations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top