can
Version:
MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.
164 lines (140 loc) • 4.82 kB
HTML
<html>
<head>
<style>
[type=date] {
border: none;
}
</style>
</head>
<body>
<todo-list></todo-list>
<script src="../../node_modules/steal/steal.js" id="demo-source"></script>
<script type="steal-module">
import {
fixture,
ObservableArray,
ObservableObject,
Reflect,
restModel,
stache,
StacheElement,
type,
} from "can";
import DeepObservable from "can-deep-observable";
class Todo extends ObservableObject {
static get props() {
return {
// `id` uniquely identifies instances of this type.
id: { type: type.maybeConvert(Number), identity: true },
complete: { type: Boolean, default: false },
dueDate: type.maybeConvert(Date),
name: type.maybeConvert(String)
};
}
static get propertyDefaults() {
return DeepObservable;
}
}
class TodoListModel extends ObservableArray {
static get props() {
return {};
}
static get items() {
return 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(30, 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);
class TodoList extends StacheElement {
static get view() {
return `
Sort By: <select value:bind="sort">
<option value="">none</option>
<option value="name">name</option>
<option value="dueDate">dueDate</option>
</select>
Show: <select value:bind="completeFilter">
<option value="">All</option>
<option value="complete">Complete</option>
<option value="incomplete">Incomplete</option>
</select>
Due: <select value:bind="dueFilter">
<option value="">Anytime</option>
<option value="today">Today</option>
<option value="week">This Week</option>
</select>
<ul>
{{# if(todosPromise.isResolved) }}
{{# for(todo of todosPromise.value) }}
<li>
<input type='checkbox' checked:bind='todo.complete' disabled/>
<label>{{ todo.name }}</label>
<input type='date' valueAsDate:bind='todo.dueDate' disabled/>
</li>
{{/ for }}
{{/ if }}
{{# if(todosPromise.isPending) }}
<li>Loading</li>
{{/ if }}
</ul>
`;
}
static get props() {
return {
sort: type.maybe(String),
completeFilter: type.maybe(String),
dueFilter: type.maybe(String),
todosPromise: {
get(){
let query = {filter: { }};
if(this.sort) {
query.sort = this.sort;
}
if(this.completeFilter) {
query.filter.complete = this.completeFilter === "complete";
}
if(this.dueFilter) {
let day = 24*60*60*1000;
let now = new Date();
let today = new Date(now.getFullYear(), now.getMonth(), now.getDate() );
if(this.dueFilter === "today") {
query.filter.dueDate = {
$gte: now.toString(),
$lt: new Date(now.getTime() + day).toString()
}
}
if(this.dueFilter === "week") {
let start = today.getTime() - (today.getDay() * day);
query.filter.dueDate = {
$gte: new Date(start).toString(),
$lt: new Date(start + 7*day).toString()
};
}
}
return Todo.getList(query);
}
}
};
}
}
customElements.define("todo-list", TodoList);
</script>
</body>
</html>