jquery ui dialog + knockoutjs

by johnpapa

HTML

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css">
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.debug.js"></script>
<h1 class="header" data-bind="text: label"></h1>

<div id="dialog" data-bind="dialog: {autoOpen: false, title: 'Dialog test' }, dialogVisible: isOpen">foo dialog</div>

<div>
    <button data-bind="click: open">Open</button>
    <button data-bind="click: close" >Close</button>
</div>

CSS

.header {
    font-size: 16px;
    font-family: sans-serif;
    font-weight: bold;
    margin-bottom: 20px;
}

JavaScript

ko.bindingHandlers.dialog = {
    init: function(element, valueAccessor) {
        var options = ko.utils.unwrapObservable(valueAccessor());
        //do in a setTimeout, so the applyBindings doesn't bind twice from element being copied and moved to bottom
        setTimeout(function() {
            $(element).dialog(options || {})
        }, 0);

        //handle disposal (not strictly necessary in this scenario)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).dialog("destroy");
        });
    },
    update: function(element, valueAccessor, allBindingsAccessor) {
        var shouldBeOpen = ko.utils.unwrapObservable(allBindingsAccessor().dialogVisible);
        $(element).dialog(shouldBeOpen ? "open" : "close");

    }
};


var viewModel = {
    label: ko.observable('dialog test'),
    isOpen: ko.observable(false),
    open: function() {
        this.isOpen(true);
    },
    close: function() {
        this.isOpen(false);
    }
};

ko.applyBindings(viewModel);