Knockout.js Examples

 

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>
This entry was posted in JavaScript, Knockout and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

This site uses Akismet to reduce spam. Learn how your comment data is processed.