$(document).ready(function() {
var viewModel = function() {
// course object construction
var course = function() {
this.id = ko.observable();
this.name = ko.observable();
this.description = ko.observable();
};
// all courses
var allCourses = ko.observableArray([]);
// selected courses
var selectedCourses = ko.observableArray([]);
// load all existing courses
var load = function() {
allCourses.push(new course().id(1).name("c#").description("Microsoft C# 4.0"));
allCourses.push(new course().id(2).name("javascript").description("JavaScript"));
allCourses.push(new course().id(3).name("WCF").description("Microsoft WCF"));
allCourses.push(new course().id(4).name("WPF").description("WPF"));
allCourses.push(new course().id(5).name("Silverlight").description("Microsoft Silverlight"));
allCourses.push(new course().id(6).name("Knockout JS").description("Knockout JS"));
};
// adding courses
var courseToAdd = ko.observable("");
var addCourse = function() {
allCourses.push(new course().id(9).description(courseToAdd()));
courseToAdd("");
};
// removing courses
var coursesAreSelected = ko.computed(function() {
return selectedCourses().length > 0;
});
var removeSelected = function() {
allCourses.removeAll(selectedCourses());
selectedCourses([]);
};
// sorting courses
var coursesExist = ko.computed(function() {
return allCourses().length > 0;
});
var sortCourses = function() {
allCourses.sort(function(left, right) {
return left.description().toLowerCase() == right.description().toLowerCase() ? 0 : (left.description().toLowerCase() < right.description().toLowerCase() ? -1 : 1);
});
};
// public members
return {
load: load,
allCourses: allCourses,
selectedCourses: selectedCourses,
coursesAreSelected: coursesAreSelected,
removeSelected: removeSelected,
coursesExist: coursesExist,
sortCourses: sortCourses,
courseToAdd: courseToAdd,
addCourse: addCourse
};
}();
viewModel.load();
ko.applyBindings(viewModel);
});
<div><span>Total Courses : </span><span data-bind="text:allCourses().length"></span>
<br />
<span>Selected Courses : </span><span data-bind="text:selectedCourses().length"></span>
<br />
</div>
<select multiple="multiple"
data-bind="options:allCourses, selectedOptions:selectedCourses, optionsText:'description'"></select>
<div>
<button data-bind="click:removeSelected, enable: coursesAreSelected">Remove</button>
<button data-bind="click:sortCourses, enable:coursesExist">Sort</button>
</div>
<form data-bind="submit:addCourse">
<span>Description: </span><input type="text" data-bind="value:courseToAdd, valueUpdate:'afterkeydown'" /><br/>
<button type="submit" data-bind="enable: courseToAdd().length > 0">Add Course</button>
</form>
div, form{margin:10px}
select
{
margin:10px;
height:300px;
width:300px;
}
External resources loaded into this fiddle: