Contents
Create Sample Project
* From VS2013, create a new ASP.NET Web Application project named, e.g. ko1
* Select Empty template and add features:
– MVC
– Web API
* Also install packages:
– jQuery
– Bootstrap
– Knockout
* See this post for details on how setup a MVC5 and SPA sample project.
Toggle Elements
* Hide/Show elements
* Add/Remove elements
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title>Test Observables</title>
</head>
<body>
<div>
<h1>Hello <span data-bind="text: computedFullName"></span>!</h1>
<div data-bind="visible: showDescription">
<h2 data-bind="text: description"></h2>
</div>
<button type="button" data-bind="click: toggleDescription">Toggel Description</button></div>
<!-- ko if: showDescription-->
<h2 data-bind="text: description"></h2>
<!-- /ko -->
<script>
function Person(firstName, lastName, description) {
var self = this;
self.firstName = firstName;
self.lastName = lastName;
self.description = description;
self.computedCnt = 0;
self.showDescription = ko.observable(false);
self.computedFullName = ko.computed(function () {
self.computedCnt++;
return self.firstName + ' ' + self.lastName;
});
self.toggleDescription = function () {
self.showDescription(!self.showDescription());
};
};
var vm = new Person('John', 'Doe', 'Sample description.');
ko.applyBindings(vm);
</script>
</body>
</html>Bind Multiple View Models on a Single Page
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title></title>
</head>
<body>
<div id="greeting1">
<h1 data-bind="text: greetings()"></h1>
</div>
<div id="greeting2">
<h1 data-bind="text: greetings()"></h1>
</div>
<script>
function Greeting(name) {
var self = this;
self.name = name;
self.greetings = function(){
return 'Hello ' + self.name + '!';
};
};
var vm1 = new Greeting('John');
ko.applyBindings(vm1, document.getElementById('greeting1'));
var vm2 = new Greeting('Jane');
ko.applyBindings(vm2, document.getElementById('greeting2'));
</script>
</body>
</html>Observable Examples
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title>Test Observables</title>
</head>
<body>
<div>
<h1>Hello <span data-bind="text: computedFullName"></span>!</h1>
<div data-bind="visible: showDescription">
<h2 data-bind="text: description"></h2>
</div>
<button type="button" data-bind="click: toggleDescription">Toggel Description</button></div>
<!-- ko if: showDescription-->
<h2 data-bind="text: description"></h2>
<!-- /ko -->
<script>
function Person(firstName, lastName, description) {
var self = this;
self.firstName = firstName;
self.lastName = lastName;
self.description = description;
self.computedCnt = 0;
self.showDescription = ko.observable(false);
self.computedFullName = ko.computed(function () {
self.computedCnt++;
return self.firstName + ' ' + self.lastName;
});
self.toggleDescription = function () {
self.showDescription(!self.showDescription());
};
};
var vm = new Person('John', 'Doe', 'Sample description.');
ko.applyBindings(vm);
</script>
</body>
</html>Template Binding Example
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title></title>
</head>
<body>
<table>
<tbody data-bind="template: {name: 'greeting-template', foreach: greetings}">
</tbody>
</table>
<br />
<div data-bind="template: {name: 'greeting-template2', foreach: greetings}">
</div>
<script type="text/html" id="greeting-template">
<tr>
<td data-bind="text: greet"></td>
<td data-bind="text: solute"></td>
<td data-bind="text: $parent.name"></td>
</tr>
</script>
<script type="text/html" id="greeting-template2">
<span data-bind="text: greet"></span>
<span data-bind="text: solute"></span>
<span data-bind="text: $parent.name"></span><br/>
</script>
<script>
function Greetings(name) {
var self = this;
self.name = name;
self.greetings = [
{
greet: 'Hello',
solute: 'Mrs.'
},
{
greet: 'Howdy',
solute: 'Dr.'
},
{
greet: 'Hey',
solute: 'Mr.'
}
];
};
var vm = new Greetings('John');
ko.applyBindings(vm);
</script>
</body>
</html>Event Binding Example
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title>Test Form1</title>
</head>
<body>
<textarea data-bind="value: myText, event: { mouseover: clearText() }"></textarea>
<br/>
Character remaining: <span data-bind="text: charRemaining"></span>
<br />
<span data-bind="text: msg"></span>
<script>
function MyText() {
var self = this;
self.myText = ko.observable('Enter text here');
self.maxCharAllowed = 25;
self.msg = ko.observable('');
self.charRemaining = ko.computed(function () {
return self.maxCharAllowed - self.myText().length;
});
self.clearText = function () {
self.myText('');
};
self.myText.subscribe(function () {
self.msg('myText changed to: ' + self.myText());
});
};
var vm = new MyText();
ko.applyBindings(vm);
</script>
</body>
</html>Extending Observables
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title>Extend Observable 1</title>
</head>
<body>
<textarea data-bind="value: myText"></textarea><br/>
Characters remaining: <span data-bind="text: charRemaining"></span>
<script>
ko.extenders.maxCharacters = function (target, max) {
var result = ko.computed({
read: target,
write: function (newValue) {
alert(newValue);
var current = target();
if (newValue.length <= max) {
target(newValue);
} else {
target(current);
target.notifySubscribers(current);
};
}
}).extend({ notify: 'always' });
return result;
};
function ViewModel() {
var self = this;
self.maxCharacters = 10;
self.myText = ko.observable('')
.extend({ maxCharacters: self.maxCharacters });
self.charRemaining = ko.computed(function () {
return self.maxCharacters - self.myText().length;
});
};
var vm = new ViewModel();
ko.applyBindings(vm);
</script>
</body>
</html>Add Custom Functions to Observables
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title>Add Custom Function to Observables</title>
</head>
<body>
List of books:
<ul>
<!-- ko foreach: books -->
<li>
<input type="checkbox" data-bind="attr: { id: isbn }, checked: owned " />
<label data-bind="attr: { for: isbn }, text: title"></label>
</li>
<!-- /ko -->
</ul>
Books you own:
<ul>
<!-- ko foreach: booksOwned -->
<li data-bind="text: title"></li>
<!-- /ko -->
</ul>
<script>
ko.observableArray.fn.booksOwned = function (property, value) {
return ko.computed(function () {
var allItems = this();
var machingItems = [];
for (var i = 0; i < allItems.length; i++) {
var current = allItems[i];
if (ko.unwrap(current[property]) === value) {
machingItems.push(current);
};
};
return machingItems;
}, this);
};
function ViewModel() {
var self = this;
self.books = ko.observableArray([
{
title: 'Book1',
isbn: '123451',
owned: ko.observable(false)
},
{
title: 'Book2',
isbn: '123452',
owned: ko.observable(false)
},
{
title: 'Book3',
isbn: '123453',
owned: ko.observable(false)
}
]);
self.booksOwned = self.books.booksOwned('owned', true);
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
</script>
</body>
</html>Form Posting with AJAX
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Test Ajax Post 1</title>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/knockout-3.0.0.js"></script>
</head>
<body>
<form data-bind="submit: save2, with: person">
<input type="text" data-bind="value: firstName"
placeholder="Enter first name" />
<br />
<input type="text" data-bind="value: lastName"
placeholder="Enter last name" />
<br />
<input type="email" data-bind="value: email"
placeholder="Enter email" />
<br />
<input type="submit" />
</form>
<script>
function ViewModel() {
var self = this;
self.person = {
firstName : ko.observable(),
lastName: ko.observable(),
email: ko.observable()
};
self.save = function (form) {
$.ajax({
url: '/Home/AjaxPost1',
data: ko.toJS(self.person),
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
error: function (xhr, status, error) {
alert(xhr.responseText);
},
success: function () {
alert('Saved!');
}
});
};
self.save2 = function (form) {
$.ajax({
url: '/Home/AjaxPost1',
data: ko.toJSON(self.person),
type: 'POST',
contentType: 'application/json',
error: function (xhr, status, error) {
alert(xhr.responseText);
},
success: function () {
alert('Saved by json!');
}
});
};
};
var vm = new ViewModel();
ko.applyBindings(vm);
</script>
</body>
</html>Receiving Data with AJAX
* TagController:
public class TagController : ApiController { public IEnumerable<string> GetAllTags() { var tags = new List<string>(); tags.Add("Tag1"); tags.Add("Tag2"); tags.Add("Tag3"); return tags; } }
* Web page:
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/knockout-3.0.0.js"></script>
<title>Test AJAX Receive One</title>
</head>
<body>
<label for="tags">Filter a tag:</label>
<input id="tags" data-bind="value: tag" /><br/>
Tags matching:
<ul>
<!-- ko foreach: matchedTags -->
<li data-bind="text: $data"></li>
<!-- /ko -->
</ul>
<script>
function ViewModel() {
var self = this;
self.availableTags = ko.observableArray([]);
self.matchedTags = ko.observableArray([]);
self.tag = ko.observable();
self.tag.subscribe(function (value) {
self.matchedTags.removeAll();
if (value !== '') {
$.ajax({
url: '/api/tag/',
type: 'GET',
contentType: 'application/json',
dataType: 'json',
success: function (data) {
self.availableTags(data);
for (var i = 0; i < self.availableTags().length; i++) {
if (self.availableTags()[i].toLowerCase().indexOf(value) >= 0) {
self.matchedTags.push(self.availableTags()[i]);
};
};
},
error: function (xhr, status, error) {
alert(xhr.responseText);
}
});
};
});
};
var vm = new ViewModel();
ko.applyBindings(vm);
</script>
</body>
</html>