$(function(){
function containsIgnoreCase(s, q){
return s.toLowerCase().indexOf(q.toLowerCase()) != -1;
}
function Post(title, text){
this.title = ko.observable(title);
this.text = ko.observable(text);
this.selected = ko.observable(false);
this.containsText = function(query){
return containsIgnoreCase(this.title(), query) || containsIgnoreCase(this.text(), query);
}
}
viewModel = {
posts : ko.observableArray([]),
filterQuery : ko.observable(''),
editMode : ko.observable(false)
}
viewModel.filteredPosts = ko.dependentObservable(function(){
var query = this.filterQuery();
if(query){
var filtered = [];
$.each(viewModel.posts(), function(i, post){
if(post.containsText(query)){
filtered.push(post);
}
});
return filtered;
}
//Not filtering
return viewModel.posts();
}, viewModel);
viewModel.selectedPosts = ko.dependentObservable(function(){
var result = [];
$.each(this.posts(), function(i, post){
if(post.selected()){
result.push(post);
}
});
return result;
}, viewModel);
viewModel.toggleEditMode = function(){
viewModel.editMode(!viewModel.editMode());
}
viewModel.newPost = function(){
viewModel.posts.push(new Post('',''));
viewModel.editMode(true);
}
viewModel.deletePosts = function(){
viewModel.posts.removeAll(viewModel.selectedPosts());
}
viewModel.posts.push(new Post('title1', 'text1'));
viewModel.posts.push(new Post('title2', 'text2'));
ko.applyBindings(viewModel);
});
<div class="container">
<table>
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Text</th>
</tr>
</thead>
<tbody data-bind="template : {name : 'postRow', foreach: filteredPosts}" />
</table>
<form>
<div class="clearfix">
<a href="#" class="btn primary" data-bind="click : newPost">New post</a>
<a href="#" class="btn primary" data-bind="visible: editMode, click: toggleEditMode">Save</a>
<a href="#" class="btn" data-bind="visible: !editMode(), click : toggleEditMode">Edit</a>
<a href="#" class="btn danger" data-bind="click : deletePosts">Delete</a>
</div>
<div class="clearfix">
<input class="xxlarge" type="text" data-bind="value : filterQuery, valueUpdate:'afterkeydown'" placeholder="Filter"/>
</div>
</form>
</div>
<script type="text/html" id="postRow">
<tr>
<td><input type="checkbox" data-bind="checked: selected" /></td>
{{if viewModel.editMode()}}
<td><input type="text" data-bind="value : title" /></td>
<td><input type="text" data-bind="value : text" /></td>
{{else}}
<td>${title}</td>
<td>${text}</td>
{{/if}}
</tr>
</script>
External resources loaded into this fiddle: