Knockout Tabs

by joshrivers

HTML

<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script src="http://knockoutjs.com/js/knockout-1.1.1.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/excite-bike/jquery-ui.css">
<div id="mytabs" data-bind="tabs: model">
</div>
<span data-bind="text: model.selectedTag "></span>
<input data-bind="value: model.selectedTag">
<script id='tabBarTemplate' type='text/x-jquery-tmpl'>
    <div id="${tabBarId}" class="ui-tabs ui-widget ui-widget-content ui-corner-all">
        <ul class="tabs ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"
        data-bind="template: {name: 'tabItemTemplate', foreach: tabItems}">
         </ul>
    </div>
</script>

<script id='tabItemTemplate' type='text/x-jquery-tmpl'>
    <li class="ui-state-default ui-corner-top" data-bind="css: { 'ui-tabs-selected': selected, 'ui-state-active': selected }, click: click">
        <a href="#${tag}"><span>${label}</span></a>
    </li>
</script>

JavaScript

model = {};
model.tabBarId = ko.observable("myBar");
model.selectedTag = ko.observable("Tab2");
model.tabItems = ko.observableArray([{
    label: "First",
    tag: "Tab1",
    selected: false},
{
    label: "Second",
    tag: "Tab2",
    selected: true},
{
    label: "Third",
    tag: "Tab3",
    selected: false}]);

ko.bindingHandlers.tabs = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        value.selectedTag(location.hash.replace("#",""));
        if (!value.selectedTag()) {value.selectedTag(value.tabItems()[0].tag);}
        $.each(value.tabItems(), function(i, item) {
            if (!ko.isObservable(item.label)) item.label=ko.observable(item.label);
            if (!ko.isObservable(item.tag)) item.tag=ko.observable(item.tag);
            item.selected=ko.dependentObservable(function() {window.console.log(this,item);return this.selectedTag()===item.tag();}, value);
            window.console.log(item.selected());
            item.click=function(){value.selectedTag(item.tag());}
        });
  
        if (!value.name) value.name = "tabBarTemplate";
        value.data = value;
        location.hash = value.selectedTag();
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        ko.bindingHandlers.template.update(element, valueAccessor, allBindingsAccessor, viewModel);
        location.hash = value.selectedTag();
    }
};
ko.applyBindings(model);