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({...