Knockout with jQuery UI Sortable
From http://groups.google.com/group/knockoutjs/browse_thread/thread/4c8f5e42d2713c77/450e409fbf1c2faa
by medmunds
HTML
<script src="http://knockoutjs.com/js/jquery.tmpl.js"></script>
<script src="http://github.com/SteveSanderson/knockout/raw/master/build/output/knockout-latest.js"></script>
<div class="container">
<ul id="sortable1" class="connectedSortable" data-bind="template: 'tmpProducts', onReceiveItem: makeUnselected"></ul>
<ul id="sortable2" class="connectedSortable" data-bind="template: 'tmpSelected', onReceiveItem: makeSelected"></ul>
<div id="jsonResults"></div>
</div>
<script type="text/html" id="tmpProducts">
{{each(i, product) Products()}}
<li data-id="${ product.Id }" class="ui-state-default">${product.Name}</li>
{{/each}}
<br />
<a href="#" data-bind="click: save">Show Results</a>
</script>
<script type="text/html" id="tmpSelected">
{{each(i, product) Selected()}}
<li data-id="${ product.Id }" class="ui-state-highlight">${product.Name}</li>
{{/each}}
</script>
CSS
#sortable1, #sortable2 {
list-style-type: none;
margin: 0;
padding: 0;
float: left;
margin-right: 10px;
background: #eee;
padding: 5px;
width: 143px;
}
#sortable1 li, #sortable2 li {
margin: 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
JavaScript
$(document).ready(function() {
$("#sortable1, #sortable2").sortable({
connectWith: ".connectedSortable",
dropOnEmpty: true,
receive: function(event, ui) {}
}).disableSelection();
var product = function(data) {
this.Id = data.Id;
this.Name = data.Name;
this.Price = data.Price;
};
function moveById(ids, fromArray, toArray) {
var moved = fromArray.remove(function(p) {
return ko.utils.arrayIndexOf(ids, p.Id.toString()) >= 0;
});
for (var i = 0; i < moved.length; i++)
toArray.push(moved[i]);
}
var viewModel = {
Products: ko.observableArray([
new product({
Id: 1,
Name: "Windows XP",
Price: 199.99
}),
new product({
Id: 2,
Name: "Windows Vista",
Price: 299.99
}),
new product({
Id: 3,
Name: "Windows 7",
Price: 239.99
})
]),
Selected: ko.observableArray([]),
save: function() {
$("#jsonResults").html(ko.toJSON(this.Selected));
},
makeSelected: function(ids) {
moveById(ids, this.Products, this.Selected)
},
makeUnselected: function(ids) {
moveById(ids, this.Selected, this.Products)
},
};
ko.bindingHandlers.onReceiveItem = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var callback = valueAccessor();
$(element).bind("sortreceive", function(event, ui) {
var receivedIds = $.map(ui.item, function(item) {
return $(item).attr("data-id")
});
callback.call(viewModel, receivedIds);
});
}
};
ko.applyBindings(viewModel);
});