UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

192 lines (170 loc) 4.76 kB
<html> <head> <style> .done { text-decoration: line-through; } </style> </head> <body> <ul id='todos'></ul> <input id='editor'/> <script type='text/ejs' id='todosEjs'> <% list(this, function( todo ) { %> <li <%= (el) -> el.data('todo',todo) %>> <input type="checkbox" class="complete" <%= todo.attr('complete') ? 'checked' : '' %>> <span class="<%= todo.attr('complete') ? 'done' : '' %>"> <%= todo.attr('name') %> </span> <a href="javascript://" class='destroy'>X</a> </li> <% }) %> </script> <h1>Welcome To History-Todo</h1> <p>History-Todo shows how to build 2 independent widgets (a list and an editor) and tie them together with a managing controller. The managing controller also listens to routes. A full write-up can be found <a href='http://localhost:3002/javascriptmvc/jmvc/docs.html#!rapidstart'>here</a>.</p> <p>Combined, this lets you:</p> <ol> <li>Click a todo, an input will appear that allows you to change the name. The change happens when you blur the input element.</li> <li>Click several todos, then use the browser's forward and back button to toggle between them.</li> </ol> <script type='text/javascript' src='../../../steal/steal.js'></script> <script type='text/javascript'> STEALDOJO = true; steal('can/model', 'can/util/fixture', 'can/view/ejs', 'can/control', 'can/control/route', function($){ // GETS TODOS FROM THE SERVER can.Model('Todo',{ findAll : "GET /todos", findOne : "GET /todos/{id}", create : "POST /todos", update : "PUT /todos/{id}", destroy : "DELETE /todos/{id}" }, {}); // WE DON'T HAVE A SERVER, USE FIXTURES // TO SIMULATE ONE: // Our fake todos var TODOS = [ {id: 1, name: "wake up", complete: true}, {id: 2, name: "take out trash", complete: false}, {id: 3, name: "do dishes", complete: false} ]; // findAll $.fixture("GET /todos", function(){ return [TODOS] }); // findOne $.fixture("GET /todos/{id}", function(orig){ // using the id, return that todo return TODOS[(+orig.data.id)-1]; }) // create var id= 4; $.fixture("POST /todos", function(){ // just need to send back a new id return {id: (id++)} }) // update $.fixture("PUT /todos/{id}", function(){ // just send back success return {}; }) // destroy $.fixture("DELETE /todos/{id}", function(){ // just send back success return {}; }); // CONTROLLERS ARE USED FOR WIDGETS LIKE A LIST OF TODOS // OR FOR MANGING WIDGETS // Organizes a list of todos can.Control("Todos",{ // called when a new Todos() is created "init" : function( element , options ){ // get all todos and render them with // a template in the element's html var self = this; can.view('todosEjs', Todo.findAll()).then(function(frag){ self.element.html(frag) }); }, // when a todo is clicked, create a 'selected' // event for others to listen to "li click" : function(li){ li.trigger('selected', li.data('todo') ); }, // when .complete is clicked, mark the todo completed "li .complete click" : function(el, ev){ el.closest('li') .data('todo') .attr('complete', el.prop('checked')) .save(); ev.stopPropagation(); }, // when .destroy is clicked, destroy the // todo "li .destroy click" : function(el, ev){ el.closest('li') .data('todo') .destroy(); ev.stopPropagation(); } }); // Editor manages editing a todo's name // call update on the editor like can.Control('Editor',{ todo : function(todo){ this.update({todo: todo}); this.setName() }, // a helper that sets the value of the input // to the todo's name setName : function(){ this.element.val(this.options.todo.name); }, // listen for changes in the todo // and update the input "{todo} updated" : function(){ this.setName(); }, "{todo} destroyed" : function(){ this.element.hide(); }, // when the input changes // update the todo instance "change" : function(){ var todo = this.options.todo todo.attr('name',this.element.val()) todo.save(); } }); // Routing puts all the widget controllers together // along with managing routes can.Control("Routing",{ init : function(){ this.editor = new Editor("#editor") new Todos("#todos"); }, // the index page "route" : function(){ $("#editor").hide(); }, "todos/:id route" : function(data){ $("#editor").show(); Todo.findOne(data, $.proxy(function(todo){ this.editor.todo(todo); }, this)) }, "li selected" : function(el, ev, todo){ can.route.attr('id',todo.id); } }); // create routing controller new Routing(document.body); }) </script> </body> </html>