Confrimation Dialog box w/knockout

by photo_tom

HTML

<script src="http://github.com/downloads/SteveSanderson/knockout/jquery.tmpl.js"></script>
<script src="https://github.com/SteveSanderson/knockout/raw/master/build/output/knockout-latest.debug.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/base/jquery-ui.css">
<form data-bind="confirmAndSubmit: {template: '#MyConfirmTemplate', submit: save}">
    <table>
        <tr>
            <th>Name</th>
            <th></th>
        </tr>
        <tbody data-bind="template: { name: 'itemsTmpl', foreach: items }"></tbody>
    </table>
    <button type="submit">Save</button>
</form>

<script id="itemsTmpl" type="text/html">
    <tr>
        <td>
            <input size="4" data-bind="value: name" />
        </td>
        <td>
            <input size="4" data-bind="value: value" />
        </td>
    </tr>
</script>

<script id="MyConfirmTemplate" type="text/x-jquery-tmpl">
    <div title="The confirmation box">
      Do you want to save the following items?
      <ul>
        {{each items()}}
        <li>${$value.name}</li>
        {{/each}}
      </ul>
    </div>
</script>

CSS

th, a { font-size: .85em; color: #444; }
td,th { padding: 5px; }
input, td { text-align: right; }

JavaScript

//this is the knockout extension:
ko.bindingHandlers.confirmAndSubmit = {
    update: function(element, valueAccessor, allBindings, viewModel) {
        $(element).submit(function(event) {

            //decompose arguments
            var settings = $.extend({
                template: "confirmTemplate",
                data: viewModel,
                submit: function() {},
                options: {}
            }, valueAccessor());

            //options for jquery ui Dialog
            var options = $.extend({
                modal: true,
                buttons: {
                    "Confirm": function() {
                        settings.submit();
                        $(this).dialog("close");
                    },
                    Cancel: function() {
                        $(this).dialog("close");
                    }
                }
            }, settings.options);
            ///alert($(settings.template).length);
            
            $(settings.template)
                .tmpl(settings.data)
                .dialog(options);
            
            event.preventDefault();
        });
    }
};

//this is the viewmodel
var viewModel = {
    items: ko.observableArray([{
        name: "one",
        value: 12},
    {
        name: "two",
        value: 1},
    {
        name: "three",
        value: 3},
    {
        name: "four",
        value: 4}]),
    save: function() {
        alert("You save it!");
    }
}

ko.applyBindings(viewModel);