Skip to content

Commit

Permalink
Fix for issue #8. Move back to handling template updates in update fu…
Browse files Browse the repository at this point in the history
…nction (to capture dependencies during parsing of binding) and initialize widget in setTimeout to allow template to render.
  • Loading branch information
rniemeyer committed Mar 9, 2012
1 parent ec68492 commit 55d89d1
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 150 deletions.
132 changes: 66 additions & 66 deletions build/knockout-sortable.js
Expand Up @@ -62,80 +62,71 @@ ko.bindingHandlers.sortable = {
ko.utils.toggleDomNodeCssClass(element, sortable.connectClass, sortable.allowDrop); ko.utils.toggleDomNodeCssClass(element, sortable.connectClass, sortable.allowDrop);
} }


//attach meta-data
ko.utils.domData.set(element, listKey, templateOptions.foreach);

//wrap the template binding //wrap the template binding
var templateArgs = [element, function() { return templateOptions; }, allBindingsAccessor, data, context]; ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
ko.bindingHandlers.template.init.apply(this, templateArgs);
ko.computed({ //initialize sortable binding after template binding has rendered in update function
read: function() { setTimeout(function() {
ko.bindingHandlers.template.update.apply(this, templateArgs); $element.sortable(ko.utils.extend(sortable.options, {
}, update: function(event, ui) {
disposeWhenNodeIsRemoved: element, var sourceParent, targetParent, targetIndex, arg,
owner: this el = ui.item[0],
}); item = ko.utils.domData.get(el, itemKey);


//initialize sortable binding if (item) {
$element.sortable(ko.utils.extend(sortable.options, { //identify parents
update: function(event, ui) { sourceParent = ko.utils.domData.get(el, parentKey);
var sourceParent, targetParent, targetIndex, arg, targetParent = ko.utils.domData.get(el.parentNode, listKey);
el = ui.item[0], targetIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), el);
item = ko.utils.domData.get(el, itemKey);

if (sortable.beforeMove || sortable.afterMove) {
if (item) { arg = {
//identify parents item: item,
sourceParent = ko.utils.domData.get(el, parentKey); sourceParent: sourceParent,
targetParent = ko.utils.domData.get(el.parentNode, listKey); sourceParentNode: el.parentNode,
targetIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), el); sourceIndex: sourceParent.indexOf(item),

targetParent: targetParent,
if (sortable.beforeMove || sortable.afterMove) { targetIndex: targetIndex,
arg = { cancelDrop: false
item: item, };
sourceParent: sourceParent, }
sourceParentNode: el.parentNode,
sourceIndex: sourceParent.indexOf(item),
targetParent: targetParent,
targetIndex: targetIndex,
cancelDrop: false
};
}


if (sortable.beforeMove) { if (sortable.beforeMove) {
sortable.beforeMove.call(this, arg, event, ui); sortable.beforeMove.call(this, arg, event, ui);
if (arg.cancelDrop) { if (arg.cancelDrop) {
$(ui.sender).sortable('cancel'); $(ui.sender).sortable('cancel');
return; return;
}
} }
}


if (targetIndex >= 0) { if (targetIndex >= 0) {
sourceParent.remove(item); sourceParent.remove(item);
targetParent.splice(targetIndex, 0, item); targetParent.splice(targetIndex, 0, item);
} }


//rendering is handled by manipulating the observableArray; ignore dropped element //rendering is handled by manipulating the observableArray; ignore dropped element
ko.utils.domData.set(el, itemKey, null); ko.utils.domData.set(el, itemKey, null);
ui.item.remove(); ui.item.remove();


//allow binding to accept a function to execute after moving the item //allow binding to accept a function to execute after moving the item
if (sortable.afterMove) { if (sortable.afterMove) {
sortable.afterMove.call(this, arg, event, ui); sortable.afterMove.call(this, arg, event, ui);
}
} }
}
},
connectWith: sortable.connectClass ? "." + sortable.connectClass : false
}));

//handle enabling/disabling sorting
if (sortable.isEnabled !== undefined) {
ko.computed({
read: function() {
$element.sortable(ko.utils.unwrapObservable(sortable.isEnabled) ? "enable" : "disable");
}, },
disposeWhenNodeIsRemoved: element connectWith: sortable.connectClass ? "." + sortable.connectClass : false
}); }));
}
//handle enabling/disabling sorting
if (sortable.isEnabled !== undefined) {
ko.computed({
read: function() {
$element.sortable(ko.utils.unwrapObservable(sortable.isEnabled) ? "enable" : "disable");
},
disposeWhenNodeIsRemoved: element
});
}
}, 0);


//handle disposal //handle disposal
ko.utils.domNodeDisposal.addDisposeCallback(element, function() { ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
Expand All @@ -144,6 +135,15 @@ ko.bindingHandlers.sortable = {


return { 'controlsDescendantBindings': true }; return { 'controlsDescendantBindings': true };
}, },
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
var templateOptions = prepareTemplateOptions(valueAccessor);

//attach meta-data
ko.utils.domData.set(element, listKey, templateOptions.foreach);

//call template binding's update with correct options
ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
},
afterRender: function(elements, data) { afterRender: function(elements, data) {
ko.utils.arrayForEach(elements, function(element) { ko.utils.arrayForEach(elements, function(element) {
if (element.nodeType === 1) { if (element.nodeType === 1) {
Expand Down
2 changes: 1 addition & 1 deletion build/knockout-sortable.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 55d89d1

Please sign in to comment.