Search code examples
javascriptjqueryjquery-uibackbone.jsjquery-ui-resizable

Working with templates + jquery ui in backbone


I have a backbone view. The view's render looks like this:

render: function()
{
    var template = _.template($("#mytemp").html() , {
        'mylabel' : "test"
    });

    this.$el.html(template);
    this.$el.css({"border" : "1px solid black"})
    this.$el.resizable({ });           
}

The problem is that the resizable plugin works by adding DOM elements to the $el. However if I use $el.html(template) that seems to wipe out these DOM elements, regardless of whether I put it before or after the resizable. Everything works the first time render is called but if render is called again, the resizable stops working.

Do I need to modify my template in some way?

http://jsbin.com/oyutey/2/edit


Solution

  • The problem is that when you do this:

    this.$el.html(template);
    

    all of the resizable's extra DOM elements get killed off; then you bind the widget:

    this.$el.resizable({ });
    

    but resizable still thinks it is properly bound so the second this.$el.resizable() call does nothing. The result is that you have resizable bound to this.$el but its DOM elements (such as the resizing handle) no longer exist.

    An easy fix is to detach the resizable before calling this.$el.html() and then rebind it after, something like this:

    render: function() {
        var template = _.template($("#mytemp").html() , {
            'mylabel' : "test"
        });
    
        if(this.rendered) // Unbind the resizable if we've already bound it
            this.$el.resizable('destroy');
        this.$el.html(template);
        this.$el.css({"border" : "1px solid black"});
        this.$el.resizable({ }); // Set up the resizable as usual.
        this.rendered = true;    // Make a note that we've already been here.
        return this;             // This is conventional so it is a good idea to do it.
    }
    

    Demo: http://jsbin.com/oyutey/3/edit