knockout-sortable -Tags variant (Asle)

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="main">
    <h3>Accordion</h3>
    <div class="high"  data-bind="sortable: { template: 'taskTmpl', data: Tags, afterMove: myDropCallback }">
    </div>

    <h3>Parking</h3>
    <div data-bind="sortable: { template: 'taskTmpl', data: parkedTags, afterMove: myDropCallback }"></div>
    <a href="#" data-bind="click: addTag">Add Tag</a>
    <hr/>
    
    <h3>Trash</h3>
    <div class="trash" data-bind="sortable: trash"></div>

    <script id="taskTmpl" type="text/html">
        <div data-bind="attr: {'id': 'tag' + tagID}">   
            <div class="accordion-header ui-widget-header" data-bind="click: $root.selectedTag"> <!-- SCENE HEADER BEGINS -->
                <table class="myaccordion-header-table" >
                    <tbody>
                        <tr>
                            <td class="left-upper header-detail" >
                            </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: tagID" ></span></td>
                        </tr>
                    </tbody>
                </table>
            </div> <!-- SCENE HEADER ENDS -->
            <div class="accordion-content"> <!--  ACCORDION CONTENTS BEGINS -->
                <span data-bind="text:text"></span>
            </div>  
        </div>
    </script>
</div>

<div id="results">
    <h3>Accordion</h3>
    <ul data-bind="foreach: Tags">
        <li data-bind="text: title"></li>
    </ul>
   ...

CSS

body {
    font-family: arial;
}

h3 {
    font-weight: bold;
    text-align: center;
}

div {
    padding: 5px;
    margin: 5px;
    border: black 1px solid;
}

p, a {
    font-size: .8em;
}

ul {
    padding-bottom: 10px;
}

.ko_container {
    width: 325px;
    min-height: 50px;
    background-color: #AAA;
}

.high {
    background-color: red;
}

.trash {
    background-color: #000;
}

.item {
    background-color: #DDD;
    cursor: move;
    text-align: center;
}

.item input {
    width: 100px;
}

#main {
    float: left;
    width: 350px;
    margin-top: 0px;
}

#results {
    margin-left: 375px;
    width: 250px;
}

JavaScript

ko.bindingHandlers.accordion = {
    init: function(element, valueAccessor) {
        var options = valueAccessor() || {};
        setTimeout(function() {
            $(element).accordion(options);
        }, 0);
        
        //handle disposal (if KO removes by the template binding)
          ko.utils.domNodeDisposal.addDisposeCallback(element, function(){
              $(element).accordion("destroy");
          });
    },
    update: function(element, valueAccessor) {
        var options = valueAccessor() || {};
        $(element).accordion("destroy").accordion(options);
    }
};


//control visibility, give element focus, and select the contents (in order)
ko.bindingHandlers.visibleAndSelect = {
    update:function (element, valueAccessor) {
        ko.bindingHandlers.visible.update(element, valueAccessor);
        if (valueAccessor()) {
            setTimeout(function () {
                $(element).find("input").focus().select();
            }, 0); //new tasks are not in DOM yet
        }
    }
};

var Tag = function (data) {
    this.tagID = data.tagID;
    this.title = ko.observable(data.title);
    this.text = ko.observable(data.text);
    
    this.titlePrefix = ko.observable("");
    this.sequenceNo = ko.observable();
    this.accScore = ko.observable();
    this.accNoOfTextbatches = ko.observable();
    this.accNoOfWords = ko.observable();
};

var ViewModel = function () {
    var self = this;

    self.Tags = ko.observableArray([
        new Tag({ tagID: 1, title: "Get dog food", text: "Elsa goes to dog food store"}),
        new Tag({ tagID: 1, title: "Mow lawn", text: "Elsa mowes the lawn"}),
        new Tag({ tagID: 1, title: "Fix car", text: "Elsa gets dirty"})
    ]);
    self.Tags.id = "high";

    self.parkedTags = ko.observableArray([
        new Tag({ tagID: 1, title: "Fix fence", text: "Elsa retrieve the hammer and some spikes"}),
        new Tag({ tagID: 1, title: "Walk dog", text: "Elsa takes her dog for a walk"}),
        new Tag({...