knockout-sortable - Asles Implementation with scenes

https://github.com/rniemeyer/knockout-sortable

by Asle Gundersby

HTML

<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<div id="extra">
    <h4 class="select">Text(s) to allocate:</h4>
    <div class="new" data-bind="sortable: $root.allocationableTextbatches">
        <div class="allocable" data-bind="text: title"></div>
    </div>
</div>
<hr/>
<div id="listAccordion">
    <div id="accordion" lass="group ui-widget ui-helper-clearfix" data-bind="jqAccordion: { },template: { name: 'scene-template', foreach: Scenes,  afterAdd: function(elem){$(elem).trigger('valueChanged');} }"></div>
</div>
<!------------------------------- scene-template: begin -------------------------------->
<script type="text/html" id="scene-template">
    <div data-bind = "attr: {'id': 'scene' + sceneID}" class="group ui-widget-content ui-corner-tr"> 
        <div class = "accordion-header ui-widget-header" > <!-- SCENE HEADER BEGINS -->
            <table class="myaccordion-header-table"> 
                <tbody> 
                    <tr><td class="left-upper header-detail"><label for="sequenceNo"> Seq: </label><span data-bind="text:sequenceNo"></span></td>
                        <td class="center" rowspan="2">
                            <h3><b><input name="title" data-bind="value: title, valueUpdate: 'afterkeydown'"/></b></h3>
                        </td>
                    </tr>
                    <tr>
                        <td class="left-bottom header-detail">Id: <span data-bind="text: sceneID"></span ></td>
                    </tr>
                </tbody>
            </table>
        </div> <!-- SCENE HEADER ENDS -->
		<div class="accordion-content"> <!--  SCENE CONTENTS BEGINS -->
             Text(s) allocated to Scene:
                    <div class="batchlist">
                        <div class="allocated" data-bind="sortable: { template: 'textb-template', data: Textbatches, allowDrop: true }"></div> 
         ...

CSS

#extra {
    clear: both;
    padding-top: 8px;
}
.new {
    border: solid 1px #444;
    background-color: #ccc;
    height: 100px;
    width: 200px;
    padding: 2px;
    border-radius: 5px;
    overflow-y:auto;
}
.new div {
    float: left;
}
.allocable {
    background-color: #444;
    color: #fff;
    border-radius: 3px;
    margin: 2px;
    padding: 1px;
    text-align: center;
    width: 97.5%;
    cursor: move;
    height:20px;
}
.batchlist {
    float: left;
    text-align: center;
    margin: 5px;
}
.batchlist span {
    font-size: .75em;
}
.allocated {
    border: 3px solid #666;
    width: 277px;
    height: 115px;
    background-color: #777;
    margin: 1px 0px 3px 0px;
    padding: 1px;
    border-radius: 4px;
    box-shadow: 0px 0px 0px #999;
    overflow-y: auto;
}
#listAccordion{
    width: 300px;
    border: 1px solid blue;
    background: #eee;
    padding: 4px;
}
#accordion {
    height: 400px;
    border: 1px solid red;
}
.accordion-header {
    font-size: 12px;
}
.accordion-header td.center {
     width: 74%;
     font-size:1.5em;
     text-align: left;
     margin: 12px 5px 5px 5px;
}

JavaScript

ko.bindingHandlers.jqAccordion = {
    init: function (element, valueAccessor) {
        var options = valueAccessor();
        $(element).accordion(options);
        $(element).bind("valueChanged", function () {
            ko.bindingHandlers.jqAccordion.update(element, valueAccessor);
        });
    },
    update: function (element, valueAccessor) {
        var options = valueAccessor();
        $(element).accordion("destroy").accordion({
            header: ".accordion-header",
            collapsible: true,
            navigation: true,
            heightStyle: "content",
            active: false
        })
        .sortable({
            axis: "x,y",
            handle: ".accordion-header",
            placeholder: "ui-state-highlight",
            start: function (event, ui) {
                sorting = true;
                //find what tab is open, false if none
                active = $(this).accordion("option", "active");
                //possibly change animation here (to make the animation instant if you like)
                $(element).accordion("option", "animate", {
                    easing: 'swing',
                    duration: 0
                });
                //close tab
                $(element).accordion({
                    active: false
                });
            },
            over: function (event, ui) {
                $(element).accordion({
                    active: false
                });
            },
            stop: function (event, ui) {
                //1st: Handle the visible impression during sorting...
                // IE doesn't register the blur when sorting so trigger focusout handlers to remove .ui-state-focus
                ui.item.children("h3").triggerHandler("focusout");
                $(element).accordion("option", "animate", {});
                active = false;
                $(element).accordion("option", "active", active);
                sorting = false;
                //2nd: Create...