Menu with knockout.js

A simple menu with knockout.js and jquery for animations.

by Doug Hill

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<div class='navigation'>
    <ul data-bind="foreach: menuEntrys">
        <li>
            <button data-bind="click: load, click: $root.selectedItem, css: { selected: isSelected }"><span data-bind="text: title"></span>

            </button>
            <ul data-bind="foreach: {data: subEntrys },  slideVisible: isSelected">
                <li>
                    <button data-bind="click: $data.load"><span data-bind="text: $data.title"></span> 
                    </button>
                </li>
            </ul>
        </li>
    </ul>
</div>
<div class="main">
     <h4>Json Result</h4>

    <ul id='result'></ul>
</div>
<div id="output" data-bind="text: ko.toJSON($root)"></div>

CSS

.navigation {
    float: left;
    width: 200px;
}
.selected {
    background-color: #ccc;
}
.main {
    height: 250px;
}
#output {
}

JavaScript

ko.bindingHandlers.slideVisible = {
    init: function (element, valueAccessor) {
        var value = valueAccessor();
        $(element).toggle(ko.utils.unwrapObservable(value));
    },
    update: function (element, valueAccessor) {
        var value = valueAccessor();
        ko.utils.unwrapObservable(value) ? $(element).slideDown(150) : $(element).slideUp(200);
    }
};

var LoadContent = function (parameter) {
    var data = {
        controler: 'DemoControler',
        action: 'Index',
        parameters: parameter
    };
    var items = [];
    $.each(data, function (key, val) {
        items.push('<li>' + key + ': ' + val + '</li>');
    });
    return items.join('');
};

var Entry = function (title) {
    this.title = title;
    this.load = function () {
        alert('Not implemented!');
    };
};

var SubmenuEntry = function (title) {
    ko.utils.extend(this, new Entry(title));
    this.load = function () {
        $('#result').html(LoadContent(this.title));
    };
};

var MenuEntry = function (title, selected, subEntrys) {
    ko.utils.extend(this, new Entry(title));
    this.subEntrys = subEntrys;
    this.load = function () {
        $('#result').html(LoadContent(this.title));
    };
    this.isSelected = ko.computed(function () {
        var selection = this === selected();
        if (selection == true) {
            this.load();
        }
        return selection;
    }, this);
};

var ViewModel = function () {
    this.selectedItem = ko.observable();
    this.menuEntrys = ko.observableArray([
    new MenuEntry("MenuItem 1", this.selectedItem, [new SubmenuEntry("Entry 1"), new SubmenuEntry("Entry 2")]),
    new MenuEntry("MenuItem 2", this.selectedItem, [new SubmenuEntry("Entry 1"), new SubmenuEntry("Entry 2"), new SubmenuEntry("Entry 3")])]);
};

ko.applyBindings(new ViewModel());