Table row slide test

by bombo

HTML

<script src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.2.0.debug.js"></script>
<script id="rowTmpl" type="text/html">
    <tr>
        <td>
            <input type="text" data-bind="value: inputVal" />
        </td>
        <td>
            <select data-bind="options: ViewModel.list, optionsValue: 'key', optionsText: 'value', optionsCaption: 'Choose...', value: selected"></select>
        </td>
        <td>
            <button data-bind="click: toggleShow"> + </button>
        </td>
    </tr>
    <tr data-bind="slideVisible: show, slideDuration:600">
        <td>Text</td>
        <td>Mehr Text</td>
    </tr>
    
</script>

<form id="myForm">
    <table>
        <thead>
            <tr>
                <td>Input</td>
                <td>Select</td>
            </tr>
            <tr>
                <td>
                    <input type="text" data-bind="value: inputVal" />
                </td>
                <td>
                    <select data-bind="options: list, optionsValue: 'key', optionsText: 'value', optionsCaption: 'Choose...', value: selected"></select>
                </td>
                <td>
                    <button data-bind="click: toggleShow"> + </button>
                </td>
            </tr>
            <tr id="more" style="display: none;">
                <td>Text</td>
                <td>Mehr Text</td>
            </tr>
        </thead>
        <tbody data-bind="template: { name: 'rowTmpl', foreach: rows }"></tbody>
    </table>
    <button data-bind="click: addRow">Add row</button>
    <div id="doSlide" style="width: 30px;">
        Hier mal ein wenig Text, der vermutlich schön sliden wird. Gna.
    </div>
</form>

JavaScript

ko.bindingHandlers.slideVisible = {
    init: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()); 
        $(element).toggle(value); 
    },
    update: function(element, valueAccessor, allBindingsAccessor) {
        // First get the latest data that we're bound to
        var value = valueAccessor(), allBindings = allBindingsAccessor();
         
        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.utils.unwrapObservable(value); 
         
        // Grab some more data from another binding property
        var duration = allBindings.slideDuration || 400; // 400ms is default duration unless otherwise specified
         
        // Now manipulate the DOM element
        if (valueUnwrapped == true) 
            $(element).slideDown(duration); // Make the element visible
        else
            $(element).slideUp(duration);   // Make the element invisible
    }
};

$("tr").click(function() { 
 
});

var viewModel = {
    list: ko.observableArray([
        { key: "1", value: "Eins" },
        { key: "2", value: "Zwei" },
        { key: "3", value: "Drei" }
    ]),
    inputVal: ko.observable(),
    rows: ko.observableArray(),
    mainInput: ko.observable(),
    selected: ko.observable()
};

viewModel.toggleShow = function() {
    $('#doSlide').slideToggle('slow');
    var tr = $('#more');
    tr.children("td").each(function() {
        $(this).wrapInner("<div></div>").children("div").slideToggle(function() {
            tr.toggle();
        });
    });
};

var Row = function(viewModel) {
    this.ViewModel = viewModel;
    this.inputVal = ko.observable();
    this.selected = ko.observable();
    this.show = ko.observable(false);
    this.toggleShow = function() {
        this.show(!this.show());
    };
};

viewModel.addRow = function() {
    this.rows.push(new Row(viewModel));
};

$(document).ready(function() {
    ko.applyBindings(viewModel);
...