jqAccordion 2ways drag'n'drop
Working...
by Asle Gundersby
HTML
<link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
Main array:
<div id="accordion" class="group ui-widget ui-helper-clearfix" data-bind="jqAccordion: { target: '#parking', source: '#accordion' },template: { name: 'scene-template', foreach: Scenes}"></div>
Park scene(s) here:
<div id="parking" class="group ui-widget ui-helper-clearfix" data-bind="jqAccordion: { target: '#accordion', source: '#parking' },template: { name: 'scene-template', foreach: parkedScenes}"></div>
<hr/>
Items in parkedScenes: <span data-bind="text: $root.parkedScenes().length"></span>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
<!---------------- scene-template: begin --------------------------->
<script type="text/html" id="scene-template"><div data-bind="attr: {'id': 'scene' + sceneID}" class="ui-widget-content">
<div class="accordion-header ui-widget-header" >
<span data-bind="text:sceneID"></span>
<span data-bind="text:title"></span>
</div>
<div class="ui-widget-content">
<span data-bind="text:text"></span>
</div >
</div></script>
<!------------------ scene-template: end ---------------------------->
CSS
#accordion{
min-height: 40px;
border: 2px solid blue;
margin: 0px 0px 10px 0px;
}
#parking{
min-height: 40px;
border: 2px solid red;
margin: 0px 0px 10px 0px;
background: cornflowerblue;
}
#droppable {
width: 150px; height: 150px;
padding: 0.5em; float: left;
margin: 10px;
}
#draggable, #draggable-nonvalid {
width: 100px; height: 100px;
padding: 0.5em; float: left;
margin: 10px 10px 10px 0px;
}
JavaScript
(function () {
var ITEMKEY = "ko_sortItem",
INDEXKEY = "ko_sourceIndex",
LISTKEY = "ko_sortList",
PARENTKEY = "ko_parentList",
DRAGKEY = "ko_dragItem",
unwrap = ko.utils.unwrapObservable,
dataGet = ko.utils.domData.get,
dataSet = ko.utils.domData.set;
//internal afterRender that adds meta-data to children
var addMetaDataAfterRender = function (elements, data) {
ko.utils.arrayForEach(elements, function (element) {
if (element.nodeType === 1) {
dataSet(element, ITEMKEY, data);
dataSet(element, PARENTKEY, dataGet(element.parentNode, LISTKEY));
}
});
};
//prepare the proper options for the template binding
var prepareTemplateOptions = function (valueAccessor, dataName) {
var result = {},
options = unwrap(valueAccessor()),
actualAfterRender;
//build our options to pass to the template engine
if (options.data) {
result[dataName] = options.data;
result.name = options.template;
} else {
result[dataName] = valueAccessor();
}
ko.utils.arrayForEach(["afterAdd", "afterRender", "as", "beforeRemove", "includeDestroyed", "templateEngine", "templateOptions"], function (option) {
result[option] = options[option] || ko.bindingHandlers.jqAccordion[option];
});
//use an afterRender function to add meta-data
if (dataName === "foreach") {
if (result.afterRender) {
//wrap the existing function, if it was passed
actualAfterRender = result.afterRender;
result.afterRender = function (element, data) {
addMetaDataAfterRender.call(data, element, data);
actualAfterRender.call(data, element, data);
};
} else {
result.afterRender =...