JSFiddle - React, Tailwind, and code Playground
by lelandrichardson
HTML
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<h3>Tasks</h3>
<form data-bind="submit: addTask">
Add task: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
<button type="submit">Add</button>
</form>
<ul data-bind="foreach: tasks, visible: tasks().length > 0">
<li>
<input type="checkbox" data-bind="checked: isDone" />
<input data-bind="value: title, disable: isDone" />
<a href="#" data-bind="click: $parent.removeTask">Delete</a>
</li>
</ul>
You have <b data-bind="text: incompleteTasks().length"> </b> incomplete task(s)
<span data-bind="visible: incompleteTasks().length == 0"> - it's beer time!</span>
<button data-bind="click: save">Save</button>
CSS
ul { list-style-type: none; margin: 1em 0; background-color: #cde; padding: 1em; border-radius: 0.5em; }
ul li a { color: Gray; font-size: 90%; text-decoration: none }
ul li a:hover { text-decoration: underline }
input:not([type]), input[type=text] { width: 30em; }
input[disabled] { text-decoration: line-through; border-color: Silver; background-color: Silver; }
textarea { width: 30em; height: 6em; }
form { margin-top: 1em; margin-bottom: 1em; }
JavaScript
function Task(data) {
this.title = ko.observable(data.title);
this.isDone = ko.observable(data.isDone);
}
function TaskListViewModel() {
// Data
var self = this;
self.tasks = ko.observableArray([]);
self.newTaskText = ko.observable();
self.incompleteTasks = ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(), function(task) {
return !task.isDone()
});
});
// Operations
self.addTask = function() {
self.tasks.push(new Task({
title: this.newTaskText()
}));
self.newTaskText("");
};
self.removeTask = function(task) {
self.tasks.remove(task)
};
self.save = function() {
$.ajax("/tasks", {
data: ko.toJSON({
tasks: self.tasks
}),
type: "post",
contentType: "application/json",
success: function(result) {
alert(result)
}
});
};
// Load initial state from server, convert it to Task instances, then populate self.tasks
$.ajax({
url: "/echo/json/",
data: {
json: JSON.stringify([
{
title: "Task Item Number 1",
isDone: false},
{
title: "Task Item Number 2",
isDone: false},
{
title: "Task Item Number 3",
isDone: false},
{
title: "Task Item Number 4",
isDone: false}
]
}),
type: "post",
contentType: "application/json",
success: function(allData) {
var mappedTasks = $.map(allData, function(item) {
return new Task(item)
});
self.tasks(mappedTasks);
}
});
}
ko.applyBindings(new TaskListViewModel());