UNPKG

can

Version:

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

181 lines (152 loc) 4.72 kB
<html> <head> <style> label { width: 200px; display: inline-block; } li { border: solid 1px white; } .selected { background-color: #d1ecf1; border-color: #bee5eb; } </style> </head> <body> <todo-app></todo-app> <script src="../../node_modules/steal/steal.js" dev-bundle></script> <script type="steal-module" id="demo-source"> import { fixture, ObservableArray, ObservableObject, restModel, StacheElement, type, } from "can"; class Todo extends ObservableObject { static props = { id: { type: type.maybeConvert(Number), identity: true }, complete: { type: type.maybeConvert(Boolean), default: false }, dueDate: { type: type.maybeConvert(Date), get default() { return new Date(); } }, name: type.maybeConvert(String) }; preventSave() { return !this.name || this.isSaving(); } } class TodoListModel extends ObservableArray { static items = type.maybeConvert(Todo); } const todoConnection = restModel({ Map: Todo, List: TodoListModel, url: "/api/todos/{id}" }); let terms = ["can you","please","","","",""], verbs = ["clean","walk","do","vaccum","organize","fold","wash","dust","pay","cook","get","take out"], subjects = ["dog","laundry","diapers","clothes","car","windows","carpet","taxes","food","gas","trash"]; let dayInMS = 24*60*60*1000; let lastWeek = new Date() - (7*dayInMS); let fourWeeks = new Date().getTime() + (4*7*dayInMS); let todoStore = fixture.store(10, function(){ return { complete: fixture.rand([true, false],1)[0], dueDate: new Date( fixture.rand(lastWeek, fourWeeks) ).toString(), name: (fixture.rand(terms,1)[0]+" "+fixture.rand(verbs,1)[0]+" "+fixture.rand(subjects,1)[0]).trim() } }, Todo); fixture("/api/todos/{id}", todoStore); fixture.delay = 1000; class TodoUpdate extends StacheElement { static view = ` {{# if(todo) }} <h3>Update Todo</h3> <form on:submit="updateTodo(scope.element, scope.event)"> <p> <label>Name</label> <input name="name" value:from='todo.name' /> </p> <p> <label>Complete</label> <input type='checkbox' name='complete' checked:from='todo.complete'/> </p> <p> <label>Date</label> <input type='date' name='dueDate' valueAsDate:from='todo.dueDate'/> </p> <button disabled:from="todo.preventSave()"> {{# if(todo.isSaving()) }}Updating{{ else }}Update{{/ if }}Todo </button> <button disabled:from="todo.preventSave()" on:click="cancelEdit()">Cancel</button> </form> {{ else }} <i>Click a todo above to edit it here.</i> {{/ if }} `; static props = { todo: type.maybeConvert(Todo) }; updateTodo(form, event) { event.preventDefault(); this.todo.assign({ name: form.name.value, complete: form.complete.checked, dueDate: form.dueDate.valueAsDate }).save().then(this.cancelEdit.bind(this)) } cancelEdit() { this.todo = null; } } customElements.define("todo-update", TodoUpdate); class TodoList extends StacheElement { static view = ` <ul> {{# if(this.todosPromise.isResolved) }} {{# for(todo of this.todosPromise.value) }} <li on:click="this.select(todo)" class="{{# eq(todo, this.selected) }}selected{{/ eq }}"> <input type='checkbox' checked:bind='todo.complete' disabled/> <label>{{ todo.name }}</label> </li> {{/ for }} {{/ if }} {{# if(this.todosPromise.isPending) }} <li>Loading</li> {{/ if }} </ul> `; static props = { todosPromise: { get default() { return Todo.getList({}); } }, selected: type.maybeConvert(Todo) }; select(todo) { this.selected = todo; } } customElements.define("todo-list", TodoList); class TodoApp extends StacheElement { static view = ` <todo-list selected:bind="scope.vars.selected"></todo-list> <todo-update todo:bind="scope.vars.selected"></todo-update> `; } customElements.define("todo-app", TodoApp); </script> </body> </html>