rniemeyer / knockout-sortable

A Knockout.js binding to connect observableArrays with jQuery UI sortable functionality
MIT License
547 stars 128 forks source link

Sortable doesn't work with filtered observableArrays #62

Closed agroskin closed 11 years ago

agroskin commented 11 years ago

Firstly, let me thank you for Knockout, it saved me from going insane with jQuery programming. It is so nice to be able to use declarative programming, templates and bindings instead.

Now, an issue. There is a problem when you use Sortable with dynamically filtered and sorted arrays. You splice and reorder the original array and remove all filtered out items, so they disappear after sorting.

I am using Knockback which nicely integrates Knockout with Backbone. Here is the problem in essence:

this.panels = ko.observableArray([ { dock: "left", order: 0 }, { dock: "right", order: 1 }, { dock: "left", order: 2 }, { dock: "right", order: 3 } ]);

this.panelsLeft = kb.collectionObservable(panels, { filters: function (panel) { return panel.dock != "left"; }, sort_attribute: "order" });

this.panelsRight = kb.collectionObservable(panels, { filters: function (panel) { return panel.dock != "right"; }, sort_attribute: "order" });

<div data-bind="sortable: panelsLeft"> ... template

<div data-bind="sortable: panelsRight"> ... template

The user sorts the left panels, and all right panels disappear, and vice versa.

Not sure how to fix the problem. It would be nice if your plugin called a callback function instead of physically reordering array items. I would simply set item.order:

callback = function( item, newIndex, etc ) { item.order = func(index); }

Maybe I have to modify Knockback filtering logic instead?

agroskin commented 11 years ago

Modified Knockback filtering logic, and the issue went away. Now, I can have multiple filtered and sorted observable collections sharing the same Backbone collection, and I can use Knockout-sortable on all of them.

Btw, I am also changing item.order field on stopSort event, so there is probably no need for a special callback.

See https://github.com/kmalakoff/knockback/issues/84