1 00:00:00,000 --> 00:00:02,000 [?music?] 2 00:00:02,000 --> 00:00:06,000 [Creating Dynamic Pages] 3 00:00:06,000 --> 00:00:10,000 So now we have our list of notes and we're displaying them right here 4 00:00:10,000 --> 00:00:13,000 and let's see what happens when we try to click on one. 5 00:00:13,000 --> 00:00:16,000 We get an error loading the page displayed here 6 00:00:16,000 --> 00:00:21,000 and we can see in our JavaScript console that there was an attempt to get this URL: 7 00:00:21,000 --> 00:00:25,000 localhost/note_ and then the id. 8 00:00:25,000 --> 00:00:27,000 Now, if you look at our code, 9 00:00:27,000 --> 00:00:34,000 what we're actually linking to is the anchor note_5d7and so on and so forth. 10 00:00:34,000 --> 00:00:39,000 So what happens is when jQuery Mobile gets a link clicked to a page 11 00:00:39,000 --> 00:00:42,000 where it can't find a div with that given id, 12 00:00:42,000 --> 00:00:48,000 is it tries to create a URL out of that id and use an AJAX request 13 00:00:48,000 --> 00:00:50,000 to try to get it back. 14 00:00:50,000 --> 00:00:55,000 Now, of course, our server doesn't have a page with note_5d7 and so on, 15 00:00:55,000 --> 00:00:59,000 so what we need to do is to actually create divs dynamically 16 00:00:59,000 --> 00:01:03,000 with the appropriate ids so that when we do click on that, 17 00:01:03,000 --> 00:01:08,000 the jQuery Mobile site is able to find the div that we need to click 18 00:01:08,000 --> 00:01:10,000 and show it like a normal page. 19 00:01:10,000 --> 00:01:13,000 Now, to construct this is not going to be too much different 20 00:01:13,000 --> 00:01:15,000 from how we constructed our list. 21 00:01:15,000 --> 00:01:18,000 Basically, what we're going to do is for each of our notes, 22 00:01:18,000 --> 00:01:23,000 we're going to create a jQuery page for it where the title is the title of the note, 23 00:01:23,000 --> 00:01:26,000 and the body will be the body text and any other information. 24 00:01:26,000 --> 00:01:32,000 We're going to keep those sort of off-screen in a big list just like we have a list of these notes, 25 00:01:32,000 --> 00:01:37,000 so every time we add a new note, we'll be adding not only a new list item to this list, 26 00:01:37,000 --> 00:01:42,000 but a whole new page item to another div that we're not seeing right now. 27 00:01:42,000 --> 00:01:47,000 So let's go to our code 28 00:01:47,000 --> 00:01:49,000 and let's take a review. 29 00:01:49,000 --> 00:01:54,000 We have our new page here and we're going to roll up our list of notes 30 00:01:54,000 --> 00:01:59,000 because we're already done with that page 31 00:01:59,000 --> 00:02:03,000 and so it's going to look a lot like it does here where we have an outer element 32 00:02:03,000 --> 00:02:07,000 that is going to serve as the list of notes and then using Backbone, 33 00:02:07,000 --> 00:02:20,000 we're going to fill in the contents of that container with all of our divs. 34 00:02:20,000 --> 00:02:22,000 So we're going to create another div 35 00:02:22,000 --> 00:02:27,000 and we're going to give this the div of "note-detail-list" 36 00:02:27,000 --> 00:02:30,000 and this div won't be really shown at any time; 37 00:02:30,000 --> 00:02:33,000 it's just going to be a container for us to fill in 38 00:02:33,000 --> 00:02:36,000 with dynamically created jQuery Mobile pages. 39 00:02:36,000 --> 00:02:39,000 So let's go to our code and work on the view 40 00:02:39,000 --> 00:02:43,000 that's going to be this list of detail pages. 41 00:02:43,000 --> 00:02:46,000 So the note for our note detail list 42 00:02:46,000 --> 00:02:48,000 is going to be a lot like our NoteListView, 43 00:02:48,000 --> 00:02:52,000 which we remember, we had an initializer and we're going to bind to a collection 44 00:02:52,000 --> 00:02:56,000 which is our list of notes, so we're going to be looking at the same collection, actually. 45 00:02:56,000 --> 00:03:00,000 And then, we're going to have the addOne for adding a new note 46 00:03:00,000 --> 00:03:03,000 and the addAll for adding all of our notes. 47 00:03:03,000 --> 00:03:07,000 I'm actually going to paste in the code for our note detail list and we'll go over it 48 00:03:07,000 --> 00:03:13,000 because it's pretty much the same code for our NoteListView. 49 00:03:13,000 --> 00:03:17,000 So here's the code for our NoteDetailList. 50 00:03:17,000 --> 00:03:21,000 Again, we're just creating a new class that's going to extend the Backbone view. 51 00:03:21,000 --> 00:03:26,000 Now, what I've done here a little bit differently is I'm actually defining the element 52 00:03:26,000 --> 00:03:29,000 we want to use inside of our definition here 53 00:03:29,000 --> 00:03:32,000 and I did that because we're only ever going to instantiate one of these 54 00:03:32,000 --> 00:03:37,000 and it's always going to be connected to this div with the "#note-detail-list" id, 55 00:03:37,000 --> 00:03:44,000 which we can see is what we just created here. 56 00:03:44,000 --> 00:03:49,000 So now we take a look at our initializer, and again, we're just using the bindAll 57 00:03:49,000 --> 00:03:53,000 to all of our methods here to make sure this is properly associated with them. 58 00:03:53,000 --> 00:03:57,000 This is exactly what we did in our NoteDetailList view, 59 00:03:57,000 --> 00:03:59,000 and we have the collection bindings, 60 00:03:59,000 --> 00:04:03,000 and this collection is going to be the same collection of all of the notes 61 00:04:03,000 --> 00:04:06,000 that we used in our NoteDetailList view. 62 00:04:06,000 --> 00:04:09,000 When we add a note, we want to call this .addOne 63 00:04:09,000 --> 00:04:13,000 and when we refresh the collection, we want to call this.addAll, 64 00:04:13,000 --> 00:04:17,000 so the same method name, same hook-up, same everything. 65 00:04:17,000 --> 00:04:20,000 And just like in our NoteDetailList, we have addOne 66 00:04:20,000 --> 00:04:24,000 and what we do is we're going to create a new view instance 67 00:04:24,000 --> 00:04:28,000 and this is going to be a NoteDetailView, which is going to be the next view 68 00:04:28,000 --> 00:04:31,000 we are going to create, and that's going to represent a page for a note. 69 00:04:31,000 --> 00:04:37,000 And then, we append the rendered view that we just created to this element, 70 00:04:37,000 --> 00:04:40,000 which is this div, so we'll be adding the new page 71 00:04:40,000 --> 00:04:43,000 onto our document. 72 00:04:43,000 --> 00:04:46,000 The addAll is pretty much similar; we empty out our current view 73 00:04:46,000 --> 00:04:52,000 and then we just go through each item in our collection and add one to it. 74 00:04:52,000 --> 00:04:56,000 So we'll save that out and the next thing we'd need to go ahead and describe 75 00:04:56,000 --> 00:04:58,000 is our NoteDetailView. 76 00:04:58,000 --> 00:05:02,000 Our NoteDetailView will represent a page for a specific note-- 77 00:05:02,000 --> 00:05:09,000 the actual viewing of that note. 78 00:05:09,000 --> 00:05:12,000 So I've pasted in the code for our NoteDetailView, 79 00:05:12,000 --> 00:05:16,000 and this is a lot like the NoteListItemView and it will represent 80 00:05:16,000 --> 00:05:19,000 an actual show page for a note. 81 00:05:19,000 --> 00:05:22,000 This will be a jQuery Mobile page 82 00:05:22,000 --> 00:05:24,000 that just shows you the details of the note. 83 00:05:24,000 --> 00:05:28,000 We're going to call this the NoteDetailView and it will inherit from the Backbone.view, 84 00:05:28,000 --> 00:05:30,000 just like we've done before. 85 00:05:30,000 --> 00:05:33,000 Now, since this view is going to be dynamically generated 86 00:05:33,000 --> 00:05:36,000 instead of attached to an existing tag on our page, 87 00:05:36,000 --> 00:05:39,000 we need to define what kind of tag we're going to base this view on 88 00:05:39,000 --> 00:05:42,000 so we're going to say tagName is "DIV". 89 00:05:42,000 --> 00:05:47,000 You remember, in our NoteListItem, we used an li because we needed an li tag 90 00:05:47,000 --> 00:05:51,000 for our list, but now we need a div tag to create a page. 91 00:05:51,000 --> 00:05:54,000 The next thing we're going to do is define a template for it, 92 00:05:54,000 --> 00:05:57,000 just like we did with our NoteListItem, 93 00:05:57,000 --> 00:06:00,000 and we're just going to do it the same way using the _.template() 94 00:06:00,000 --> 00:06:04,000 and grab the contents of "#note-detail-template" 95 00:06:04,000 --> 00:06:09,000 which we'll define in a moment in our index.html page. 96 00:06:09,000 --> 00:06:11,000 And now we get to our initializer. 97 00:06:11,000 --> 00:06:15,000 We're going to have our bindAll to make sure our render is called correctly 98 00:06:15,000 --> 00:06:17,000 with the correct this, 99 00:06:17,000 --> 00:06:21,000 and render is the function that will actually update the contents of our view 100 00:06:21,000 --> 00:06:25,000 with the data that needs to be displayed. 101 00:06:25,000 --> 00:06:29,000 And also in our initializer, there are a couple of things we need to do. 102 00:06:29,000 --> 00:06:32,000 Since the view will automatically create the div for us, 103 00:06:32,000 --> 00:06:36,000 we are going to need to set some attributes on this div 104 00:06:36,000 --> 00:06:39,000 to make it act like a jQuery Mobile page. 105 00:06:39,000 --> 00:06:44,000 So what we're going to do is we're going to jQueryify our $(this.el) 106 00:06:44,000 --> 00:06:51,000 and we're going to use the attr method, which allows us to set attributes on an HTML tag. 107 00:06:51,000 --> 00:06:56,000 So the first thing we're going to do is set the attribute "data-role" to "page", 108 00:06:56,000 --> 00:07:02,000 and we've seen this before; this just says to jQuery Mobile that this should act like a page. 109 00:07:02,000 --> 00:07:06,000 Then we also want to set the id, and this is important. 110 00:07:06,000 --> 00:07:11,000 This is how jQuery Mobile is going to be able to locate the div that we need to load 111 00:07:11,000 --> 00:07:13,000 when we click on a note in the list view. 112 00:07:13,000 --> 00:07:21,000 So to construct the id, we're just going to take "note_" = this.model.id 113 00:07:21,000 --> 00:07:27,000 so this should match any of the links to the specific notes in our page. 114 00:07:27,000 --> 00:07:31,000 Finally, we're going to bind the change event in this.model 115 00:07:31,000 --> 00:07:34,000 to render the page, so this.render. 116 00:07:34,000 --> 00:07:39,000 And now we get down to our render function, which is a lot like our previous view. 117 00:07:39,000 --> 00:07:43,000 We're just going to wrap jQuery around this element $(this.el) 118 00:07:43,000 --> 00:07:47,000 and then we're going to set the HTML to render (this.template 119 00:07:47,000 --> 00:07:51,000 and we'll pass the note into that template. 120 00:07:51,000 --> 00:07:54,000 (this.template({note: this.model})); 121 00:07:54,000 --> 00:08:05,000 So the next thing we need to do is actually define the template in our HTML file. 122 00:08:05,000 --> 00:08:10,000 I've just pasted in the template for our NoteDetailView. 123 00:08:10,000 --> 00:08:14,000 I've passed it into a script tag with a type of "text/template" 124 00:08:14,000 --> 00:08:16,000 just like we did for our previous template, 125 00:08:16,000 --> 00:08:19,000 and given it the id of "note-detail-template" 126 00:08:19,000 --> 00:08:22,000 which is what our view code is expecting to find. 127 00:08:22,000 --> 00:08:26,000 The code for this template is going to be what's inside of our div 128 00:08:26,000 --> 00:08:29,000 with the data-role of page. 129 00:08:29,000 --> 00:08:33,000 We're not going to have the outer div because that's automatically generated by our view, 130 00:08:33,000 --> 00:08:38,000 so this is what goes inside of a div with the data-role of page. 131 00:08:38,000 --> 00:08:42,000 So we're going to have a header, which is defined right here, 132 00:08:42,000 --> 00:08:46,000 and so we have a div with a data-role="header". 133 00:08:46,000 --> 00:08:51,000 We're going to put in our own Back button linked to the homepage 134 00:08:51,000 --> 00:08:53,000 and you can see we have the data-role button here, 135 00:08:53,000 --> 00:08:57,000 we have the data-icon of "arrow-l" and a data-rel of "back" 136 00:08:57,000 --> 00:09:01,000 so this is how we've created our manual Back buttons before. 137 00:09:01,000 --> 00:09:05,000 It just has the text of Back. 138 00:09:05,000 --> 00:09:08,000 Then, here in our h1 is where we have our dynamic bit 139 00:09:08,000 --> 00:09:11,000 which is served by the template. 140 00:09:11,000 --> 00:09:14,000 So we have this note object which is our model instance, 141 00:09:14,000 --> 00:09:18,000 and to get the title, we'll call .get("title"), 142 00:09:18,000 --> 00:09:25,000 and this will be replaced into the contents of our h1 tag right here. 143 00:09:25,000 --> 00:09:29,000 After our header, we'll have the div with the data-role of "content" 144 00:09:29,000 --> 00:09:32,000 and just for now, I'm going to get the body from our note 145 00:09:32,000 --> 00:09:35,000 and just place it into the content. 146 00:09:35,000 --> 00:09:39,000 So now we have the view code written and our templates written. 147 00:09:39,000 --> 00:09:44,000 All we need to do is go back to our application code and instantiate the actual views 148 00:09:44,000 --> 00:09:50,000 so our pages will be generated. 149 00:09:50,000 --> 00:10:02,000 So I'm about to paste in our code to instantiate our NoteDetailList view. 150 00:10:02,000 --> 00:10:09,000 And here's our code: we're going to assign to App.views.notes = new NoteDetailList({ 151 00:10:09,000 --> 00:10:15,000 and we're going to pass into that the collection of App.collections.all_notes 152 00:10:15,000 --> 00:10:22,000 which is the same collection we passed to our alphabetical note list in the previous view, 153 00:10:22,000 --> 00:10:25,000 so both of these should stay in sync. 154 00:10:25,000 --> 00:10:29,000 So let's see if this is going to work in our browser. 155 00:10:29,000 --> 00:10:31,000 So I'm just going to refresh this. 156 00:10:31,000 --> 00:10:34,000 We didn't get any syntax errors, which is great, 157 00:10:34,000 --> 00:10:37,000 so we'll see what happens when we click on My Note. 158 00:10:37,000 --> 00:10:43,000 Awesome! So now we've navigated to note_10b3 159 00:10:43,000 --> 00:10:45,000 and we have the title of My Note, 160 00:10:45,000 --> 00:10:47,000 and we can see that there's no content. 161 00:10:47,000 --> 00:10:51,000 We should be able to go back and try another note. 162 00:10:51,000 --> 00:10:56,000 Cool, let's just take a look at a few more. 163 00:10:56,000 --> 00:10:57,000 Awesome. 164 00:10:57,000 --> 00:11:02,000 So now, it looks like we're able to view our notes, go back and forth, 165 00:11:02,000 --> 00:11:08,000 and let's go ahead and try to create a New Note. 166 00:11:08,000 --> 00:11:11,000 New Page Test 167 00:11:11,000 --> 00:11:16,000 This is the content. 168 00:11:16,000 --> 00:11:19,000 And when we save this out, 169 00:11:19,000 --> 00:11:24,000 we should be able to go to All Notes. 170 00:11:24,000 --> 00:11:28,000 We'll see New Page Test 171 00:11:28,000 --> 00:11:30,000 and This is the content. 172 00:11:30,000 --> 00:11:35,000 Now, the final test is to see if the actual note can be bookmarked and refreshed, 173 00:11:35,000 --> 00:11:40,000 so to test this out, I'm on the note page, and if I refresh it, 174 00:11:40,000 --> 00:11:42,000 it looks like it comes back. 175 00:11:42,000 --> 00:11:45,000 It looks like it loads up just fine. 176 00:11:45,000 --> 00:11:49,000 If you're having a little bit of trouble understanding what's going on here, 177 00:11:49,000 --> 00:11:53,000 let's take a look at what this page looks like without jQuery Mobile loaded. 178 00:11:53,000 --> 00:11:56,000 So let's go back here 179 00:11:56,000 --> 00:12:00,000 and let's go back to our index.html file, 180 00:12:00,000 --> 00:12:04,000 and what I'm going to do is I'm just going to mess up this URL 181 00:12:04,000 --> 00:12:07,000 so that it does not load jQuery Mobile. 182 00:12:07,000 --> 00:12:11,000 So if we refresh, we can see what we have here is our homepage, 183 00:12:11,000 --> 00:12:16,000 which is just a list to All Notes and Nearest Notes. 184 00:12:16,000 --> 00:12:21,000 We have our New Note page down here. 185 00:12:21,000 --> 00:12:26,000 We have our All Notes page, and this list is generated by Backbone.js, 186 00:12:26,000 --> 00:12:31,000 so every time we add a new note, it will be appended to this list. 187 00:12:31,000 --> 00:12:37,000 And now, what we have here is inside of this div--if we inspect it here, 188 00:12:37,000 --> 00:12:47,000 let's take a look here-- 189 00:12:47,000 --> 00:12:52,000 we can see that we have the div with the id of NoteDetailList 190 00:12:52,000 --> 00:12:55,000 and then, inside of that are all of our different note pages 191 00:12:55,000 --> 00:13:03,000 all with the correct ids, so this list is being dynamically generated by Backbone as well. 192 00:13:03,000 --> 00:13:07,000 We should actually be able to create a new note without the help of jQuery Mobile, 193 00:13:07,000 --> 00:13:09,000 so let's see what happens here. 194 00:13:09,000 --> 00:13:13,000 We might get an error, but let's see what happens. 195 00:13:13,000 --> 00:13:18,000 So let's just do a Plain Note Test 196 00:13:18,000 --> 00:13:20,000 and Some content. 197 00:13:20,000 --> 00:13:23,000 Hopefully, we should be able to save this, 198 00:13:23,000 --> 00:13:30,000 and we can see there was a little update that happened here. 199 00:13:30,000 --> 00:13:35,000 Just like Backbone added a Plain Note Test here, 200 00:13:35,000 --> 00:13:40,000 it also went down here and created the note for us here, 201 00:13:40,000 --> 00:13:44,000 and all of this is going to be turned into jQuery Mobile 202 00:13:44,000 --> 00:13:46,000 as soon as it's loaded. 203 00:13:46,000 --> 00:13:50,000 So let's go ahead and fix this and refresh, 204 00:13:50,000 --> 00:13:54,000 and we can see that it still works. 205 00:13:54,000 --> 00:13:59,000 We can go back to our Plain Note Test and see that the data is persisted. 206 00:13:59,000 --> 00:14:02,000 Let's take a look at it in the mobile. 207 00:14:02,000 --> 00:14:08,000 I'm going to go ahead and change this and I'm going to go ahead and refresh. 208 00:14:08,000 --> 00:14:11,000 We see we only have one note on our mobile app 209 00:14:11,000 --> 00:14:16,000 and if we click it, we can see we have our First Mobile Note and we have some text. 210 00:14:16,000 --> 00:14:19,000 We can go back all the way to the home. 211 00:14:19,000 --> 00:14:21,000 Let's do a Second Note 212 00:14:21,000 --> 00:14:31,000 With Some Awesome Text 213 00:14:31,000 --> 00:14:33,000 and let's save it out. 214 00:14:33,000 --> 00:14:40,000 It flies away, we click on All Notes, and we get our Second Note and we can click to it. 215 00:14:40,000 --> 00:14:44,000 We can even refresh from this page, 216 00:14:44,000 --> 00:14:48,000 so we can go to Second Note and we can look and see that all of our text is here, 217 00:14:48,000 --> 00:15:23,000 and we can even refresh the page and see that it still works.