So here we are, DOM events in backbone js. I got 8 emails so far requesting for a lesson to understand DOM events in backbone js. To all of them I just replied, I have that thing in my list. Just wait a little and another thing was why you are doing everything on console. I want to something on browser window too. For those folks here is the first episode when we are doing something on browser window. Anyways. Coming back to the lesson. We want to add code for listening to dom events in backbone js.
Lets see what we have right now.
- We have Person, PersonView, PeopleCollection, PeopleCollectionView
- App namespace
- Template a personView
- We learnt validations, although we are not using that in our sample codes.
Ok. In this lesson what we are supposed to do:
- You can see list of people
- You can click on any person and edit his/her name
- You can add a new person
- You can delete a person record.
You can see a live demo of final outcome here.
I am starting the application with this code and I hope you can understand all of it very easily. If not then checkout the previous lessons.
(function() { window.App = { Models: {}, Collections: {}, Views: {} }; window.template = function(id) { return _.template( $('#' + id).html() ); }; // Person Model App.Models.Person = Backbone.Model.extend({ defaults: { name: 'Guest User', age: 30, occupation: 'worker' } }); // A List of People App.Collections.People = Backbone.Collection.extend({ model: App.Models.Person }); // View for all people App.Views.People = Backbone.View.extend({ tagName: 'ul', render: function() { this.collection.each(function(person) { var personView = new App.Views.Person({ model: person }); this.$el.append(personView.render().el); }, this); return this; } }); // The View for a Person App.Views.Person = Backbone.View.extend({ tagName: 'li', template: template('personTemplate'), render: function() { this.$el.html( this.template(this.model.toJSON()) ); return this; } }); var peopleCollection = new App.Collections.People([ { name: 'Mohit Jain', age: 26 }, { name: 'Taroon Tyagi', age: 25, occupation: 'web designer' }, { name: 'Rahul Narang', age: 26, occupation: 'Java Developer' } ]); var peopleView = new App.Views.People({ collection: peopleCollection }); $(document.body).append(peopleView.render().el); })(); |
So very first thing that we want to do is: listening to click event on a particular person record. This is simple to do in PersonView (check inline comments)
// The View for a Person App.Views.Person = Backbone.View.extend({ tagName: 'li', template: template('personTemplate'), // we defined a click event and on any click we can calling a showAlert function // which is just displaying a alert box. events: { 'click' : 'showAlert' }, showAlert: function(){ alert("You clicked me"); }, render: function() { this.$el.html( this.template(this.model.toJSON()) ); return this; } }); |
Lets move to browser and lets see what happens when we click on a person record.
Clik here to view.

12 Listening to Dom events in backbone js
A useful tip:
What if you just want to trigger click only for the name of the person not on age or occupation ie some internal element. Pretty easy..
events: { 'click strong' : 'showAlert' }, |
Ok, so we got the basic idea how to add dom events in our PersonView. We can add all other events like dblclick, mouseover etc.
Lets move ahead and removing all the code we added for click event etc. Lets first modify our template ie personTemplate and add two button edit and delete.
<script id="personTemplate" type="text/template"> <span><strong><%= name %></strong> (<%= age %>) - <%= occupation %></span> <button class="edit">Edit</button> <button class="delete">Delete</button> </script> |
Lets head back to console to see what we have.
Clik here to view.

12 Listening to Dom events in backbone js
So now we do have two buttons for each row, edit and delete, which don’t do anything but we have them. So now head back to your PersonView and add events for these two one by one.
Edit Button:
For edit we need to do these things:
- Get the previous Content
- Take new user input
- Update the view with new content
Lets add click events and getting new values.
events: { 'click .edit' : 'editPerson' }, editPerson: function(){ var newName = prompt("Please enter the new name", this.model.get('name')); this.model.set('name', newName); }, |
Trying this on browser.
- Loading the page will display three people record
- Click on edit and lets update the name of the user using promt
- Again call render and append peopleView in dom. ie $(document.body).append(peopleView.render().el);
Image may be NSFW.
Clik here to view.
Cool, So now we want whenever we change the name of the person, it should just update the view of that person. We can do this just by binding a function (also known as listeners). So just simply bind onchange event in PersonView like this:
initialize: function(){ this.model.on('change', this.render, this); }, |
So basically we are re-rendering the personView whenever its model is changing. Now hit refresh and try to change the name of the person using prompt. It will just re-render the view automatically :) Cool naa..!!!
But the problem is when you hit cancel.. boom.. Check the code with inline comments…
// The View for a Person App.Views.Person = Backbone.View.extend({ tagName: 'li', template: template('personTemplate'), initialize: function(){ this.model.on('change', this.render, this); }, events: { 'click .edit' : 'editPerson' }, editPerson: function(){ var newName = prompt("Please enter the new name", this.model.get('name')); if (!newName) return; // don't do anything if cancel is pressed.. this.model.set('name', newName); }, render: function() { this.$el.html( this.template(this.model.toJSON()) ); return this; } }); |
Another way of doing this can be setting validations that we learnt in lesson 4 ie validations in models
Also add valdiations by trimming the white spaces etc.
So thats supercool for editing a person name. Now lets move ahead and add a functionality for deleting a record.
Deleting a record:
- Lets first bind a delete click
- Now call a destroy method which will destroy the object
- Add a listener for destroy
- Remove the element from DOM, will be called by listner
Here is the code for that, pretty simple. (Check inline comments..)
// The View for a Person App.Views.Person = Backbone.View.extend({ tagName: 'li', template: template('personTemplate'), initialize: function(){ this.model.on('change', this.render, this); this.model.on('destroy', this.remove, this); // 3. Adding a destroy announcer.. }, events: { 'click .edit' : 'editPerson', 'click .delete' : 'DestroyPerson' /// 1. Binding a Destroy for the listing to click event on delete button.. }, editPerson: function(){ var newName = prompt("Please enter the new name", this.model.get('name')); if (!newName) return; this.model.set('name', newName); }, DestroyPerson: function(){ this.model.destroy(); // 2. calling backbone js destroy function to destroy that model object }, remove: function(){ this.$el.remove(); // 4. Calling Jquery remove function to remove that HTML li tag element.. }, render: function() { this.$el.html( this.template(this.model.toJSON()) ); return this; } }); |
I hope are with me without losing the grip of the what happening here.
Now lets do add a new person record.
So lets create a simple form in index.html ie
<form id="addPerson" action=""> <input type="text" placeholder="Name of the person"> <input type="submit" value="Add Person"> </form> |
Now we need to do these things:
- Create a newView for newPerson and Read value from the textbox
- Create a new model instance
- Add into the collection
- Render the new collection
So pretty simple:
Defining a new view for record
App.Views.AddPerson = Backbone.View.extend({ el: '#addPerson', # referencing the form itself. events: { 'submit': 'submit' // binding submit click to submit function.. }, submit: function(e) { e.preventDefault(); // preventing default submission.. var newPersonName = $(e.currentTarget).find('input[type=text]').val(); // getting new form values.. var person = new App.Models.Person({ name: newPersonName });// creating a new person object.. this.collection.add(person); // adding this to current collection.. } }); |
We are adding person to collection to adding listeners for it.
// View for all people App.Views.People = Backbone.View.extend({ tagName: 'ul', initialize: function() { this.collection.on('add', this.addOne, this); // listeners/anouncers for the collection on add.. }, // refactored render method... render: function() { this.collection.each(this.addOne, this); return this; }, // called from render method of collection view.. addOne: function(person) { var personView = new App.Views.Person({ model: person }); this.$el.append(personView.render().el); } }); |
var addPersonView = new App.Views.AddPerson({ collection: peopleCollection }); peopleView = new App.Views.People({ collection: peopleCollection }); $(document.body).append(peopleView.render().el); |
Hit refresh and now try add, edit and delete. Super Cool ;) Thats all about listening to dom events in backbone js and so called mini project.
If you are facing any issues. Checkout the source code files at github. I will be creating more and more directories in the same repo regarding each post. Still if you have any doubts contact me or you can comment on the blog post itself.
The post 12 Listening to DOM events in backbone js – Learning Backbone js appeared first on Code Beer Startups.