FREELessons: 24Length: 1.8 hours

Next lesson playing in 5 seconds

  • Overview
  • Transcript

4.3 Managing DOM Events

Now that we have created our data which is a collection full of models and we've also created a couple of views to display those, the next step would be allowing our visitor to interact with that data in some way. Right? We want them to be able to do something with the data and then we want to do something in response to their action. So, let's start by doing something very basic. Let's add a remove button to each one of these list items and when they click remove we'll move that item from the collection. Of course our view will be listening for this remove action and it will go ahead and remove the displayed view. So, let's start by adding that remove button to our template. After we have our h3, let's add a paragraph after that and in here let's add a button, and we'll just give it a class called remove and we will give it the text Remove. Okay so, if we look at our browser and refresh you can see that now all of our items have a Remove button. So, now we need to listen for a click on that button. So, let's go back to our app.js and that button is part of the BookView template. So, let's add on events Property. Now the events property is an object and this object registers events by their key. So, the key for each one of these will be a string and they go in the form event and then selector. Right? So, we want to listen for a click event on .remove. .Remove of course is the class remove on this button and when that happens we want to call a certain function and we'll call this function remove model. I should note that we can't just call it remove because that is a built-in backbone view for removing the view from the dom. You would call view .remove and we'll probably get around to calling that here. So, we don't want to override it by accident. So, let's create the removeModel function. Of course this will take a dome event as its parameter because this is a regular dome event listener and what we want to do here is remove this model from the collection. So, what we can do is say this.model.collection to get a reference to the collection that this model is in and then we can say don't remove this.model. This way we can remove the model that is being displayed by this view from the collection. All right, now if we come back here and let me open our JavaScript console again. Let me throw it up on the side this time. I'll refresh the page one more time and right now if I do books.length you can see that it is five as you would expect because that's the number we're displaying. So, let's click remove on Jules Verne. Now of course nothing changes in our view. However, if we do books.length again you can that now it's only four because we've just removed Around The World in 80 Days from the collection. However, we're not yet doing anything to update this view. So, that is our next step. What we need to do is have our BooksView here. This is the one that manages all of the individual BookViews. We want it to listen for any remove events. So, let's have an initialize function here and you'll remember we talked about initialize functions way back in one of the first lessons and this is where we're going to register our event. So, we're going to use this which refers to our view. This.listenTo and we're going to listen to this.collection and we're listening for our add event and when it happens, we want to call this.removeModel. All right? So, let's add a remove model event and for now let's just have a console.log so that you can see that this connection is actually working and actually, sorry, this should be the remove event. There we go. Not the add event. So, we're listening onto the collection for the remove event and when that happens we call Remove model. So, I will go ahead and click Remove and as you can see we now have would remove here displayed in the console. So, this means that in this function we can go ahead and figure out how to remove this view. Now there are a couple of ways we could do this. One of the simplest ways would be to add this view that we are creating here to our model as a property and then that way for when we come down here to remove model. Remember the model will be the first parameter here because that is the first parameter when we have a remove event and so we could do model.view.remove. Let's try that. So, from in here where we loop over this collection. Instead of creating a book view variable let's change this to model.view equals the new BookView and then here we can just say model.view.render.el. That way down here we can say model.view.remove and it will remove the view from the dom. So, now if we refresh this page we can click and you can see the book is removed from the view. That's not always the best way to do it. A lot of people would rather that our models not be aware of the view that they are working with. Another way to do this would be to have an array within BooksView here that kept track of each one of these models maybe by their ID. So, for example let's just add an extra property to our BooksView here and we could call this Children. Just make an empty array for now and then inside this collection here we can say children.model.cid is what we'll use and because of that we should actually make this children an object because cid will be a string. This is just the client side ID and then down here we can say children.[model.cid].render and then down here we could say this.children and that reminds me of course I should be saying this.children up here. Sorry. This.children and this.children which means we need to pass a context of this for our each loop here. Okay. So, back down to here. This .children square back at model .cid.remove and this should work in exactly the same fashion. So, let's refresh the page and if I remove this you can see it's removed from the list. So, what about adding items to the list? We should add a little form for this. Let's create another view. We'll create a template for it here and instead of calling this BooksViewTemplate let's call it AddBookViewTemplate and we'll make this really simple. And we'll just have a paragraph with an input with an ID of title and then we'll create another one of those with an ID of author and I guess we should put some labels so we'll just title and author just like that. All right. So, now let's create this view. So, we'll create it right here and we'll call this the add book view and we'll get the template. I'll copy a template line from up above. AddBookViewTemplate and the rendering part will be really easy. This.el.innerHTML = this.template. No need for anything else. The interesting thing is when the form is submitted which reminds me we're going to need a button. So, let me copy that from our other button and run paragraph for the button and we'll give the class add and we'll say add new book. Excellent. So, now in our events object here we can list for click on .add and we will call addBook and we have the addBook function down here. All right and so what we can do is say this.collection because this view will have a collection. This.collection.add and we will just add an object here and we can set its title equal to this dollar sign. What should we call that? We can give it an ID with title. So, we'll say hash title dot val and then we can say author equals this dollar sign hash author dot val and there we go. So, now if we render this view we'll create an addBookView right here and we'll say new AddBookView and don't forget to give it our collection and then let's just render it just above our other view. So, we'll create our AddBookView right there. All right. Now if I refresh this page you can see that we have our form displayed at the top and so I'll just add a book here. XXX and YYY. If I click add new book nothing of course happens just yet but notice if we go books.length you can see we now have six books. So, we are adding the book but we're just not displaying that new book. So, we need to have the BooksView our collection view listen for a new book. So, we'll say this.listenTo(this.collection and we want to listen for an add and when we do that let's do this.addBook. Okay. Let's write an addBook method. So, I'll put that above removeModel here and maybe to keep this consistent we should call this removeBook instead. So, we have addBook and removeBook. So, now let's say addBook and of course this function takes that model as its first parameter. And so now we can do pretty much exactly what we did inside this each here. So, we can say this.children[model.cid] equals a new BookView and we pass in that model and then we need to get that unordered list and append it to it. So, let me just copy this line from right here and let's say this.$('ul') and append that there. And this actually means we could use this add book function from right here with collection because it does pretty much the exact same thing. So, I'm gonna remove this function entirely from here and change this to this.addBook and I would rather bind this like this than pass this as a context parameter. So, we'll say this time addBook.bind it to this and that means we don't need this ul here. Excellent. So, that cleans up our render block quite a bit. All right. So, that should successfully render new books when we add them. So, let's give that a try. If we refresh the page we have five books showing here. Let's add XXX and YYY and we add this book and now you can see, right down at the bottom, we have our new book XXX and YYY and we can go ahead and remove books from our list as well. So, we're successfully adding and removing books. Let's do one more thing. Let's update the number of books in our list whenever we add or remove an item. So, to do this we're going to need a way to capture that value. Right now it's just here in parentheses let's add a span inside those parentheses and so now we want to, let's add two more event handlers. This.listenTothis.collection and we'll listen for remove and we'll have this.updateNumber and let's copy that and add another one for adds. So, whenever we want to add or remove we want to run our update number function. So, we'll add this right in the bottom here. We can have updateNumber. Let's just find that span with this.$ span and we'll just set it to text equal to this.collection.length. There we go. Okay. So, now I refresh the page. We have five books. Let's add a new one and now when I click add new book you can see this goes up to six and her book is added to the bottom and if I remove books. Five, four, three, two, one, zero. Add new book and we're back up to one. So, there you go. This video started out as a simple look at how Backbone handles DOM events but as you can see combining DOM events with Backbone's own events we can create pretty complex web applications.

Back to the top