Using backbone.js with jQuery UI Modals

In backbone, the views control all the events that are happening “in this part of html code” (in other words, your associated template). This is really good for decoupling your code and makes for a very good code structure but can be a headacke when trying to control popups.

Events in Backbone are handled automatically with jQuery delegates, thing is, the dom element that delegates all the events need to be outside the view or declared when the view is generated. This is a problem with modals because the element we are trying to delegate on is not in the view and needs to be called by jQuery UI on render.

Fortunately something you can do after your view content is rendered is changing the this.el element to the view container and call this.delegateEvents(this.events) . This will take care of the event binding problem.

Example

wedapp.view.TasksForm = Backbone.View.extend({
	events: {
		"click #completedbtn" : 	"complete",
		"click #updatebtn" : 		"update",
		"click #savebtn" : 		"save",
		"click #closebtn" : 		"close",
	},
	render: function() {
		var formString = this.template(this.model.toJSON());
		$(formString).dialog({
			autoOpen: true,
			height: 460,
			width: 350,
			title:"Tasks",
			modal: true
		})
		this.el = $(".dialogForm");
		this.delegateEvents(this.events)
		return this;
	},
	initialize : function(){
		_.bindAll(this,"render")
		this.template = _.template($("#task_form_tpl").html());
		this.render().el;
	},
	complete: function(){
		console.log("test")
	},
	update: function(){
		console.log("test")
	},
	save: function(){
		console.log("test")
	},
	close: function(){
		console.log("test")
	},
});

“Voila!”

That should help you get your popups going!

Cedric Dugas is a front-end veteran with more than 9 years under the belt, between his open source projects & entrepreneurial ambitions he is a product architect at CakeMail. Why don't you follow him on twitter.

10 Comments on "Using backbone.js with jQuery UI Modals"

  1. Ryan says:

    Thanks, this saved me a lot of angst! It works great with Facebox – here’s a coffeescript example:

    html = @template()
    $.facebox(html)
    @el = $(“#facebox”)
    @delegateEvents(@events)

  2. Veera says:

    Whoa! Saved my day. I was trying to integrate JQuery Simple Modal and having issues with event delegation. This post just helped me to resolve the issue.

    Thanks a lot.

  3. zkov says:

    I am trying to get up to speed on backbone and jquery and just curios where did you declared your dialogForm and whether you have source code for this?!

  4. Mike says:

    There’s a better way (at least, as of 0.9.22).

    Instead of:
    this.el = $(“.dialogForm”);
    this.delegateEvents(this.events);

    Just call “setElement” on the view:
    this.setElement(‘.dialogForm’);

    It handles setting up this.el, this.$el, and undelegating/re-delegating events for you. It also behaves properly regardless of being passed a string or jquery object — setElement(‘.dialogForm’) vs setElement($(‘.dialogForm’)).

  5. Mike says:

    I tried the above snippet for the modal popup. However, i got the javascript error on $(formString).dialog and error message is:

    Uncaught TypeError: Object [object Object] has no method ‘dialog’

    Any idea what i am missing?

    Thanks.

  6. CajunD says:

    Yea, this is an interesting solution to the problem, but without seeing the template, or understanding where $(“.dialogForm”) is coming from, I’m not getting much from this. It would be great if you can demonstrate what your template looks like. Thanks.

  7. patrice says:

    thanks for this post, working perfetcly by only replacing :
    this.el = $(“.dialogForm”);
    with
    this.$el = $(“.dialogForm”);
    using (backbone 1.0.0).
    @zkov : dialogForm the class of some div encapsulating your form within task_form_tpl

  8. patrice says:

    even better,
    doesnt need to use .dialogForm, attach this.$el to dialog instead and that is it.

    render: function() {
    formString = this.template(currentUser.toJSON());
    this.$el = $(formString).dialog({
    autoOpen: true,
    height: 460,
    width: 600,
    title:"Login",
    modal: true
    })
    // this.$el = $(".dialogForm"); -- not needed anymore
    this.delegateEvents(this.events)
    return this;
    }

  9. Govind says:

    Hi,

    I am trying to use with Jquery Mobile and not able to get the dialog properly. Can you share the markup or small sample.

    Thanks,

Trackbacks for this post

  1. Backbone.js and JQueryUI Dialog – events not binding | PHP Developer Resource

Leave a Reply to Veera