/app/public/js/vendor/backbone/docs/todos.html
HTML | 765 lines | 516 code | 249 blank | 0 comment | 0 complexity | 1f7cf2cd0f1abeaef1482c88631fc580 MD5 | raw file
1<!DOCTYPE html>
2
3<html>
4<head>
5 <title>todos.js</title>
6 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
7 <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
8 <link rel="stylesheet" media="all" href="docco.css" />
9</head>
10<body>
11 <div id="container">
12 <div id="background"></div>
13
14 <ul id="jump_to">
15 <li>
16 <a class="large" href="javascript:void(0);">Jump To …</a>
17 <a class="small" href="javascript:void(0);">+</a>
18 <div id="jump_wrapper">
19 <div id="jump_page">
20
21
22 <a class="source" href="backbone.localstorage.html">
23 backbone.localstorage.js
24 </a>
25
26
27 <a class="source" href="todos.html">
28 todos.js
29 </a>
30
31 </div>
32 </li>
33 </ul>
34
35 <ul class="sections">
36
37 <li id="title">
38 <div class="annotation">
39 <h1>todos.js</h1>
40 </div>
41 </li>
42
43
44
45 <li id="section-1">
46 <div class="annotation">
47
48 <div class="pilwrap ">
49 <a class="pilcrow" href="#section-1">¶</a>
50 </div>
51 <p>An example Backbone application contributed by
52<a href="http://jgn.me/">Jérôme Gravel-Niquet</a>. This demo uses a simple
53<a href="backbone-localstorage.html">LocalStorage adapter</a>
54to persist Backbone models within your browser.
55
56</p>
57<p>Load the application once the DOM is ready, using <code>jQuery.ready</code>:
58</p>
59
60 </div>
61
62 <div class="content"><div class='highlight'><pre>$(<span class="keyword">function</span>(){</pre></div></div>
63
64 </li>
65
66
67 <li id="section-2">
68 <div class="annotation">
69
70 <div class="pilwrap for-h2">
71 <a class="pilcrow" href="#section-2">¶</a>
72 </div>
73 <h2>Todo Model</h2>
74
75 </div>
76
77 </li>
78
79
80 <li id="section-3">
81 <div class="annotation">
82
83 <div class="pilwrap ">
84 <a class="pilcrow" href="#section-3">¶</a>
85 </div>
86 <p>Our basic <strong>Todo</strong> model has <code>title</code>, <code>order</code>, and <code>done</code> attributes.
87</p>
88
89 </div>
90
91 <div class="content"><div class='highlight'><pre> <span class="keyword">var</span> Todo = Backbone.Model.extend({</pre></div></div>
92
93 </li>
94
95
96 <li id="section-4">
97 <div class="annotation">
98
99 <div class="pilwrap ">
100 <a class="pilcrow" href="#section-4">¶</a>
101 </div>
102 <p>Default attributes for the todo item.
103</p>
104
105 </div>
106
107 <div class="content"><div class='highlight'><pre> defaults: <span class="keyword">function</span>() {
108 <span class="keyword">return</span> {
109 title: <span class="string">"empty todo..."</span>,
110 order: Todos.nextOrder(),
111 done: <span class="literal">false</span>
112 };
113 },</pre></div></div>
114
115 </li>
116
117
118 <li id="section-5">
119 <div class="annotation">
120
121 <div class="pilwrap ">
122 <a class="pilcrow" href="#section-5">¶</a>
123 </div>
124 <p>Toggle the <code>done</code> state of this todo item.
125</p>
126
127 </div>
128
129 <div class="content"><div class='highlight'><pre> toggle: <span class="keyword">function</span>() {
130 <span class="keyword">this</span>.save({done: !<span class="keyword">this</span>.get(<span class="string">"done"</span>)});
131 }
132
133 });</pre></div></div>
134
135 </li>
136
137
138 <li id="section-6">
139 <div class="annotation">
140
141 <div class="pilwrap for-h2">
142 <a class="pilcrow" href="#section-6">¶</a>
143 </div>
144 <h2>Todo Collection</h2>
145
146 </div>
147
148 </li>
149
150
151 <li id="section-7">
152 <div class="annotation">
153
154 <div class="pilwrap ">
155 <a class="pilcrow" href="#section-7">¶</a>
156 </div>
157 <p>The collection of todos is backed by <em>localStorage</em> instead of a remote
158server.
159</p>
160
161 </div>
162
163 <div class="content"><div class='highlight'><pre> <span class="keyword">var</span> TodoList = Backbone.Collection.extend({</pre></div></div>
164
165 </li>
166
167
168 <li id="section-8">
169 <div class="annotation">
170
171 <div class="pilwrap ">
172 <a class="pilcrow" href="#section-8">¶</a>
173 </div>
174 <p>Reference to this collection's model.
175</p>
176
177 </div>
178
179 <div class="content"><div class='highlight'><pre> model: Todo,</pre></div></div>
180
181 </li>
182
183
184 <li id="section-9">
185 <div class="annotation">
186
187 <div class="pilwrap ">
188 <a class="pilcrow" href="#section-9">¶</a>
189 </div>
190 <p>Save all of the todo items under the <code>"todos-backbone"</code> namespace.
191</p>
192
193 </div>
194
195 <div class="content"><div class='highlight'><pre> localStorage: <span class="keyword">new</span> Backbone.LocalStorage(<span class="string">"todos-backbone"</span>),</pre></div></div>
196
197 </li>
198
199
200 <li id="section-10">
201 <div class="annotation">
202
203 <div class="pilwrap ">
204 <a class="pilcrow" href="#section-10">¶</a>
205 </div>
206 <p>Filter down the list of all todo items that are finished.
207</p>
208
209 </div>
210
211 <div class="content"><div class='highlight'><pre> done: <span class="keyword">function</span>() {
212 <span class="keyword">return</span> <span class="keyword">this</span>.where({done: <span class="literal">true</span>});
213 },</pre></div></div>
214
215 </li>
216
217
218 <li id="section-11">
219 <div class="annotation">
220
221 <div class="pilwrap ">
222 <a class="pilcrow" href="#section-11">¶</a>
223 </div>
224 <p>Filter down the list to only todo items that are still not finished.
225</p>
226
227 </div>
228
229 <div class="content"><div class='highlight'><pre> remaining: <span class="keyword">function</span>() {
230 <span class="keyword">return</span> <span class="keyword">this</span>.without.apply(<span class="keyword">this</span>, <span class="keyword">this</span>.done());
231 },</pre></div></div>
232
233 </li>
234
235
236 <li id="section-12">
237 <div class="annotation">
238
239 <div class="pilwrap ">
240 <a class="pilcrow" href="#section-12">¶</a>
241 </div>
242 <p>We keep the Todos in sequential order, despite being saved by unordered
243GUID in the database. This generates the next order number for new items.
244</p>
245
246 </div>
247
248 <div class="content"><div class='highlight'><pre> nextOrder: <span class="keyword">function</span>() {
249 <span class="keyword">if</span> (!<span class="keyword">this</span>.length) <span class="keyword">return</span> <span class="number">1</span>;
250 <span class="keyword">return</span> <span class="keyword">this</span>.last().get(<span class="string">'order'</span>) + <span class="number">1</span>;
251 },</pre></div></div>
252
253 </li>
254
255
256 <li id="section-13">
257 <div class="annotation">
258
259 <div class="pilwrap ">
260 <a class="pilcrow" href="#section-13">¶</a>
261 </div>
262 <p>Todos are sorted by their original insertion order.
263</p>
264
265 </div>
266
267 <div class="content"><div class='highlight'><pre> comparator: <span class="string">'order'</span>
268
269 });</pre></div></div>
270
271 </li>
272
273
274 <li id="section-14">
275 <div class="annotation">
276
277 <div class="pilwrap ">
278 <a class="pilcrow" href="#section-14">¶</a>
279 </div>
280 <p>Create our global collection of <strong>Todos</strong>.
281</p>
282
283 </div>
284
285 <div class="content"><div class='highlight'><pre> <span class="keyword">var</span> Todos = <span class="keyword">new</span> TodoList;</pre></div></div>
286
287 </li>
288
289
290 <li id="section-15">
291 <div class="annotation">
292
293 <div class="pilwrap for-h2">
294 <a class="pilcrow" href="#section-15">¶</a>
295 </div>
296 <h2>Todo Item View</h2>
297
298 </div>
299
300 </li>
301
302
303 <li id="section-16">
304 <div class="annotation">
305
306 <div class="pilwrap ">
307 <a class="pilcrow" href="#section-16">¶</a>
308 </div>
309 <p>The DOM element for a todo item...
310</p>
311
312 </div>
313
314 <div class="content"><div class='highlight'><pre> <span class="keyword">var</span> TodoView = Backbone.View.extend({</pre></div></div>
315
316 </li>
317
318
319 <li id="section-17">
320 <div class="annotation">
321
322 <div class="pilwrap ">
323 <a class="pilcrow" href="#section-17">¶</a>
324 </div>
325 <p>... is a list tag.
326</p>
327
328 </div>
329
330 <div class="content"><div class='highlight'><pre> tagName: <span class="string">"li"</span>,</pre></div></div>
331
332 </li>
333
334
335 <li id="section-18">
336 <div class="annotation">
337
338 <div class="pilwrap ">
339 <a class="pilcrow" href="#section-18">¶</a>
340 </div>
341 <p>Cache the template function for a single item.
342</p>
343
344 </div>
345
346 <div class="content"><div class='highlight'><pre> template: _.template($(<span class="string">'#item-template'</span>).html()),</pre></div></div>
347
348 </li>
349
350
351 <li id="section-19">
352 <div class="annotation">
353
354 <div class="pilwrap ">
355 <a class="pilcrow" href="#section-19">¶</a>
356 </div>
357 <p>The DOM events specific to an item.
358</p>
359
360 </div>
361
362 <div class="content"><div class='highlight'><pre> events: {
363 <span class="string">"click .toggle"</span> : <span class="string">"toggleDone"</span>,
364 <span class="string">"dblclick .view"</span> : <span class="string">"edit"</span>,
365 <span class="string">"click a.destroy"</span> : <span class="string">"clear"</span>,
366 <span class="string">"keypress .edit"</span> : <span class="string">"updateOnEnter"</span>,
367 <span class="string">"blur .edit"</span> : <span class="string">"close"</span>
368 },</pre></div></div>
369
370 </li>
371
372
373 <li id="section-20">
374 <div class="annotation">
375
376 <div class="pilwrap ">
377 <a class="pilcrow" href="#section-20">¶</a>
378 </div>
379 <p>The TodoView listens for changes to its model, re-rendering. Since there's
380a one-to-one correspondence between a <strong>Todo</strong> and a <strong>TodoView</strong> in this
381app, we set a direct reference on the model for convenience.
382</p>
383
384 </div>
385
386 <div class="content"><div class='highlight'><pre> initialize: <span class="keyword">function</span>() {
387 <span class="keyword">this</span>.listenTo(<span class="keyword">this</span>.model, <span class="string">'change'</span>, <span class="keyword">this</span>.render);
388 <span class="keyword">this</span>.listenTo(<span class="keyword">this</span>.model, <span class="string">'destroy'</span>, <span class="keyword">this</span>.remove);
389 },</pre></div></div>
390
391 </li>
392
393
394 <li id="section-21">
395 <div class="annotation">
396
397 <div class="pilwrap ">
398 <a class="pilcrow" href="#section-21">¶</a>
399 </div>
400 <p>Re-render the titles of the todo item.
401</p>
402
403 </div>
404
405 <div class="content"><div class='highlight'><pre> render: <span class="keyword">function</span>() {
406 <span class="keyword">this</span>.$el.html(<span class="keyword">this</span>.template(<span class="keyword">this</span>.model.toJSON()));
407 <span class="keyword">this</span>.$el.toggleClass(<span class="string">'done'</span>, <span class="keyword">this</span>.model.get(<span class="string">'done'</span>));
408 <span class="keyword">this</span>.input = <span class="keyword">this</span>.$(<span class="string">'.edit'</span>);
409 <span class="keyword">return</span> <span class="keyword">this</span>;
410 },</pre></div></div>
411
412 </li>
413
414
415 <li id="section-22">
416 <div class="annotation">
417
418 <div class="pilwrap ">
419 <a class="pilcrow" href="#section-22">¶</a>
420 </div>
421 <p>Toggle the <code>"done"</code> state of the model.
422</p>
423
424 </div>
425
426 <div class="content"><div class='highlight'><pre> toggleDone: <span class="keyword">function</span>() {
427 <span class="keyword">this</span>.model.toggle();
428 },</pre></div></div>
429
430 </li>
431
432
433 <li id="section-23">
434 <div class="annotation">
435
436 <div class="pilwrap ">
437 <a class="pilcrow" href="#section-23">¶</a>
438 </div>
439 <p>Switch this view into <code>"editing"</code> mode, displaying the input field.
440</p>
441
442 </div>
443
444 <div class="content"><div class='highlight'><pre> edit: <span class="keyword">function</span>() {
445 <span class="keyword">this</span>.$el.addClass(<span class="string">"editing"</span>);
446 <span class="keyword">this</span>.input.focus();
447 },</pre></div></div>
448
449 </li>
450
451
452 <li id="section-24">
453 <div class="annotation">
454
455 <div class="pilwrap ">
456 <a class="pilcrow" href="#section-24">¶</a>
457 </div>
458 <p>Close the <code>"editing"</code> mode, saving changes to the todo.
459</p>
460
461 </div>
462
463 <div class="content"><div class='highlight'><pre> close: <span class="keyword">function</span>() {
464 <span class="keyword">var</span> value = <span class="keyword">this</span>.input.val();
465 <span class="keyword">if</span> (!value) {
466 <span class="keyword">this</span>.clear();
467 } <span class="keyword">else</span> {
468 <span class="keyword">this</span>.model.save({title: value});
469 <span class="keyword">this</span>.$el.removeClass(<span class="string">"editing"</span>);
470 }
471 },</pre></div></div>
472
473 </li>
474
475
476 <li id="section-25">
477 <div class="annotation">
478
479 <div class="pilwrap ">
480 <a class="pilcrow" href="#section-25">¶</a>
481 </div>
482 <p>If you hit <code>enter</code>, we're through editing the item.
483</p>
484
485 </div>
486
487 <div class="content"><div class='highlight'><pre> updateOnEnter: <span class="keyword">function</span>(e) {
488 <span class="keyword">if</span> (e.keyCode == <span class="number">13</span>) <span class="keyword">this</span>.close();
489 },</pre></div></div>
490
491 </li>
492
493
494 <li id="section-26">
495 <div class="annotation">
496
497 <div class="pilwrap ">
498 <a class="pilcrow" href="#section-26">¶</a>
499 </div>
500 <p>Remove the item, destroy the model.
501</p>
502
503 </div>
504
505 <div class="content"><div class='highlight'><pre> clear: <span class="keyword">function</span>() {
506 <span class="keyword">this</span>.model.destroy();
507 }
508
509 });</pre></div></div>
510
511 </li>
512
513
514 <li id="section-27">
515 <div class="annotation">
516
517 <div class="pilwrap for-h2">
518 <a class="pilcrow" href="#section-27">¶</a>
519 </div>
520 <h2>The Application</h2>
521
522 </div>
523
524 </li>
525
526
527 <li id="section-28">
528 <div class="annotation">
529
530 <div class="pilwrap ">
531 <a class="pilcrow" href="#section-28">¶</a>
532 </div>
533 <p>Our overall <strong>AppView</strong> is the top-level piece of UI.
534</p>
535
536 </div>
537
538 <div class="content"><div class='highlight'><pre> <span class="keyword">var</span> AppView = Backbone.View.extend({</pre></div></div>
539
540 </li>
541
542
543 <li id="section-29">
544 <div class="annotation">
545
546 <div class="pilwrap ">
547 <a class="pilcrow" href="#section-29">¶</a>
548 </div>
549 <p>Instead of generating a new element, bind to the existing skeleton of
550the App already present in the HTML.
551</p>
552
553 </div>
554
555 <div class="content"><div class='highlight'><pre> el: $(<span class="string">"#todoapp"</span>),</pre></div></div>
556
557 </li>
558
559
560 <li id="section-30">
561 <div class="annotation">
562
563 <div class="pilwrap ">
564 <a class="pilcrow" href="#section-30">¶</a>
565 </div>
566 <p>Our template for the line of statistics at the bottom of the app.
567</p>
568
569 </div>
570
571 <div class="content"><div class='highlight'><pre> statsTemplate: _.template($(<span class="string">'#stats-template'</span>).html()),</pre></div></div>
572
573 </li>
574
575
576 <li id="section-31">
577 <div class="annotation">
578
579 <div class="pilwrap ">
580 <a class="pilcrow" href="#section-31">¶</a>
581 </div>
582 <p>Delegated events for creating new items, and clearing completed ones.
583</p>
584
585 </div>
586
587 <div class="content"><div class='highlight'><pre> events: {
588 <span class="string">"keypress #new-todo"</span>: <span class="string">"createOnEnter"</span>,
589 <span class="string">"click #clear-completed"</span>: <span class="string">"clearCompleted"</span>,
590 <span class="string">"click #toggle-all"</span>: <span class="string">"toggleAllComplete"</span>
591 },</pre></div></div>
592
593 </li>
594
595
596 <li id="section-32">
597 <div class="annotation">
598
599 <div class="pilwrap ">
600 <a class="pilcrow" href="#section-32">¶</a>
601 </div>
602 <p>At initialization we bind to the relevant events on the <code>Todos</code>
603collection, when items are added or changed. Kick things off by
604loading any preexisting todos that might be saved in <em>localStorage</em>.
605</p>
606
607 </div>
608
609 <div class="content"><div class='highlight'><pre> initialize: <span class="keyword">function</span>() {
610
611 <span class="keyword">this</span>.input = <span class="keyword">this</span>.$(<span class="string">"#new-todo"</span>);
612 <span class="keyword">this</span>.allCheckbox = <span class="keyword">this</span>.$(<span class="string">"#toggle-all"</span>)[<span class="number">0</span>];
613
614 <span class="keyword">this</span>.listenTo(Todos, <span class="string">'add'</span>, <span class="keyword">this</span>.addOne);
615 <span class="keyword">this</span>.listenTo(Todos, <span class="string">'reset'</span>, <span class="keyword">this</span>.addAll);
616 <span class="keyword">this</span>.listenTo(Todos, <span class="string">'all'</span>, <span class="keyword">this</span>.render);
617
618 <span class="keyword">this</span>.footer = <span class="keyword">this</span>.$(<span class="string">'footer'</span>);
619 <span class="keyword">this</span>.main = $(<span class="string">'#main'</span>);
620
621 Todos.fetch();
622 },</pre></div></div>
623
624 </li>
625
626
627 <li id="section-33">
628 <div class="annotation">
629
630 <div class="pilwrap ">
631 <a class="pilcrow" href="#section-33">¶</a>
632 </div>
633 <p>Re-rendering the App just means refreshing the statistics -- the rest
634of the app doesn't change.
635</p>
636
637 </div>
638
639 <div class="content"><div class='highlight'><pre> render: <span class="keyword">function</span>() {
640 <span class="keyword">var</span> done = Todos.done().length;
641 <span class="keyword">var</span> remaining = Todos.remaining().length;
642
643 <span class="keyword">if</span> (Todos.length) {
644 <span class="keyword">this</span>.main.show();
645 <span class="keyword">this</span>.footer.show();
646 <span class="keyword">this</span>.footer.html(<span class="keyword">this</span>.statsTemplate({done: done, remaining: remaining}));
647 } <span class="keyword">else</span> {
648 <span class="keyword">this</span>.main.hide();
649 <span class="keyword">this</span>.footer.hide();
650 }
651
652 <span class="keyword">this</span>.allCheckbox.checked = !remaining;
653 },</pre></div></div>
654
655 </li>
656
657
658 <li id="section-34">
659 <div class="annotation">
660
661 <div class="pilwrap ">
662 <a class="pilcrow" href="#section-34">¶</a>
663 </div>
664 <p>Add a single todo item to the list by creating a view for it, and
665appending its element to the <code><ul></code>.
666</p>
667
668 </div>
669
670 <div class="content"><div class='highlight'><pre> addOne: <span class="keyword">function</span>(todo) {
671 <span class="keyword">var</span> view = <span class="keyword">new</span> TodoView({model: todo});
672 <span class="keyword">this</span>.$(<span class="string">"#todo-list"</span>).append(view.render().el);
673 },</pre></div></div>
674
675 </li>
676
677
678 <li id="section-35">
679 <div class="annotation">
680
681 <div class="pilwrap ">
682 <a class="pilcrow" href="#section-35">¶</a>
683 </div>
684 <p>Add all items in the <strong>Todos</strong> collection at once.
685</p>
686
687 </div>
688
689 <div class="content"><div class='highlight'><pre> addAll: <span class="keyword">function</span>() {
690 Todos.each(<span class="keyword">this</span>.addOne, <span class="keyword">this</span>);
691 },</pre></div></div>
692
693 </li>
694
695
696 <li id="section-36">
697 <div class="annotation">
698
699 <div class="pilwrap ">
700 <a class="pilcrow" href="#section-36">¶</a>
701 </div>
702 <p>If you hit return in the main input field, create new <strong>Todo</strong> model,
703persisting it to <em>localStorage</em>.
704</p>
705
706 </div>
707
708 <div class="content"><div class='highlight'><pre> createOnEnter: <span class="keyword">function</span>(e) {
709 <span class="keyword">if</span> (e.keyCode != <span class="number">13</span>) <span class="keyword">return</span>;
710 <span class="keyword">if</span> (!<span class="keyword">this</span>.input.val()) <span class="keyword">return</span>;
711
712 Todos.create({title: <span class="keyword">this</span>.input.val()});
713 <span class="keyword">this</span>.input.val(<span class="string">''</span>);
714 },</pre></div></div>
715
716 </li>
717
718
719 <li id="section-37">
720 <div class="annotation">
721
722 <div class="pilwrap ">
723 <a class="pilcrow" href="#section-37">¶</a>
724 </div>
725 <p>Clear all done todo items, destroying their models.
726</p>
727
728 </div>
729
730 <div class="content"><div class='highlight'><pre> clearCompleted: <span class="keyword">function</span>() {
731 _.invoke(Todos.done(), <span class="string">'destroy'</span>);
732 <span class="keyword">return</span> <span class="literal">false</span>;
733 },
734
735 toggleAllComplete: <span class="function"><span class="keyword">function</span> <span class="params">()</span> {</span>
736 <span class="keyword">var</span> done = <span class="keyword">this</span>.allCheckbox.checked;
737 Todos.each(<span class="function"><span class="keyword">function</span> <span class="params">(todo)</span> {</span> todo.save({<span class="string">'done'</span>: done}); });
738 }
739
740 });</pre></div></div>
741
742 </li>
743
744
745 <li id="section-38">
746 <div class="annotation">
747
748 <div class="pilwrap ">
749 <a class="pilcrow" href="#section-38">¶</a>
750 </div>
751 <p>Finally, we kick things off by creating the <strong>App</strong>.
752</p>
753
754 </div>
755
756 <div class="content"><div class='highlight'><pre> <span class="keyword">var</span> App = <span class="keyword">new</span> AppView;
757
758});</pre></div></div>
759
760 </li>
761
762 </ul>
763 </div>
764</body>
765</html>