Giter Site home page Giter Site logo

knockout-sortable's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

knockout-sortable's Issues

draggable binding interferes with $parent

Looks like $parent context variable is incorrect inside elements that use the draggable binding. Example fiddle:

http://jsfiddle.net/pjbWC/5/

This fiddle prints out $data and $parent values for array elements, they turn out to be equal, which I didn't expect.

In source of the binding, update() method, there's this line:

var templateOptions = prepareTemplateOptions(valueAccessor, "data");

The issue goes away if I change "data" to something else:

var templateOptions = prepareTemplateOptions(valueAccessor, "draggable");

I don't understand this well at all, so not sure if this is correct fix, and what side-effects it may have.

Sortable doesn't work with filtered observableArrays

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?

Sorting is funky with string literals

I'm using sortable binding on KO's observableArray with literal string values;

self.items = ko.observableArray(["foo", "bar", "duplicate", "duplicate", "duplicate"]);

When I sort any of the 'duplicate' items, the rest disappears. I understand this happens because sortable binding removes elements with obsevableArray.remove() method. It would be great if it removed items by index instead.

Support for "as"

Knockout-sortable could definitely benefit from an implementation of the "as" option, which has been added to the knockout foreach binding in 2.2.0.

Option Start doesn't fire at Start time

I created a sortable with the following:

gt; div data-bind="sortable: {data: dataA]array, allowDrop: true, afterMove: dropCallback, options: {start: PresentationTransform}}, text: name.toUpperCase(), attr: { 'class': 'droppable clsFolder_' + name.toUpperCase(), 'id': name } " lt;

Couldn't find an example to insert options, so I can't be sure that is the way to enter an option,

If that is the way, then the PresentationTransform is not being raised by the start option at the calling of:

$element.sortable(ko.utils.extend(sortable.options

I tried with the beforeMove, but it is raised at Update time (although it looks like it does at the same time than afterMove.

Is there an example for the use of options / start?

In any case, I need to alter the presentation of the droppable object before it is moved.

Thanks in advance

Miguel Delgado

d

CancelDrop does not seem to be working when assigned via a binding vs. globally.

I have a binding against a collection which looks like this:

                    <div class="rletter-transactions" data-bind="sortable: { data: details, template: 'transactionDetailTemplate', beforeMove: function(arg) { $parent.canMoveTransaction(this, arg); }, afterMove: function(arg) { $parent.afterMoveTransactionToLetter(this,arg); } }">
...
</div>

<script type="text/html" id="transactionDetailTemplate">
<div style="padding: 2px; margin: 3px; cursor: pointer; min-width: 200px; display: block; clear: both; background-color: White; border-radius: 4px;">
    <span data-bind="text: fundDescription"></span> -
    <span data-bind="text: withdrawlAmount().toFixed(2)"></span> -
    <span data-bind="text: withdrawlType"></span>
</div>
</script>

and my Script# code looks like:

        public void CanMoveTransaction(RedemptionLettersModel self, KnockoutSortableBeforeMoveOptions<TransactionDetail> arg)
        {
            if (((int)Type.GetField(arg.TargetParent, "FundId")) != 0)
            {
                if (arg.Item.FundCanCombineTransactionsAcrossFunds.GetValue())
                {
                    if (((bool)Type.GetField(arg.TargetParent, "FundCanCombineTransactionsAcrossFunds")) && !arg.CancelDrop)
                    {
                        if (((RedemptionFlag)Type.GetField(arg.TargetParent, "RedemptionType")) == RedemptionFlag.Partial)
                        {
                            // all transactions within the target collection are of the same quarter id.
                            int numItems = arg.TargetParent.GetItems().Length;
                            for (int i = 0; i < numItems; i++)
                            {
                                int targetFundId = ((int)Type.GetField(arg.TargetParent, "FundId"));
                                int itemFundId = arg.Item.FundId.GetValue();
                                if (targetFundId != itemFundId && !arg.CancelDrop)
                                {
                                    Script.Alert("Cannot add this transaction into selected letter.  Transactions within selected letter are for a different period than the selected transaction.");
                                    arg.CancelDrop = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        Script.Alert("Cannot add this transaction into selected letter.  Transactions within selected letter do not allow combined transactions across funds.");
                        arg.CancelDrop = true;
                    }
                }
                else
                {
                    if (((int)Type.GetField(arg.TargetParent, "FundId")) != arg.Item.FundId.GetValue() && !arg.CancelDrop)
                    {
                        Script.Alert("Cannot mix funds without having the 'Combine Funds' flag set on the Fund.");
                        arg.CancelDrop = true;
                    }

                    if (((RedemptionFlag)Type.GetField(arg.TargetParent, "RedemptionType")) == RedemptionFlag.Full && !arg.CancelDrop)
                    {
                        Script.Alert("Can only have 1 full redemption on this letter.");
                        arg.CancelDrop = true;
                    }
                }
            }
        }

When I debug the resulting javascript in Firefox, I'm getting the alerts that the arg.CancelDrop=true are being set, but the collection is still affected. Is this an issue with not binding globally, or haven't I set this up right?


When I debug this in FireFox, and go into the section that reacts to the beforeMove call in the Sortable plugin, it seems like ui.sender should be populated, but it isn't (since source and destination lists are not equal, the code says to use ui.sender). Not sure if this is a Script# issue due to scoping, or if this is a genuine issue in the Sortable plugin for Knockout.js

Draggable and afterReceive

To facilitate the custom handling of a receive from a draggable, I altered the receive method like this:

receive: function (event, ui) {
    dragItem = ko.utils.domData.get(ui.item[0], DRAGKEY);
    if (dragItem && dragItem.clone) {
        dragItem = dragItem.clone();
    }
    if (sortable.afterReceive) {
        sortable.afterReceive(this, dragItem, event, ui);
    }
}

In the sortable KO binding you can then specify the afterReceive callback function in the same way as afterMove and beforeMove.

Are you able to add this into the next build?

Thanks

Chris

isEnabled/allowDrop don't update when set by a computed expression

I have a <div> that shows one of several sortable lists, selectable from a drop-down. Some of these lists are read-only. My binding looks like this:

<div class="board" data-bind="css: { readonly: readOnly }>
    <select data-bind="options: lists"></select>
    <div class="board-body" data-bind="sortable: { template: 'listItemTmpl', data: items, isEnabled: !readOnly(), allowDrop: !readOnly() }">
    </div>
</div>

The property readOnly is an observable and updates when lists is changed. If the user changes from a read-only list to a writeable one, the binding doesn't update the isEnabled or allowDrop behaviors.

My current workaround is to use a computed observable writeable that just returns !readOnly(), and this works as expected. So it's not show-stopping, but every other binding lets you use expressions at any point, so this should probably be made consistent.

UI element loses binding to viewmodel object after using CancelDrop

Hi Ryan!
Thanks for the plugin, it saved me a lot of time.
Just wanted to outline an issue that i found. I've got 2 linked lists and i want to disable manual sorting inside the second list. So i used the cancelDrop option. I also have +/- buttons on the list items that are also moving the items between lists by relocating them between the observable arrays.
The issue is that when I try to use manual sorting and the action is being cancelled by cancelDrop, and then try to move that item to the linked list by removing the assoctiated object from from one array and adding to another, the UI item element is not being destroyed. I think that could be something with the jquery.sortable("cancel") that you use, but i am not sure.

You can replicate the issue on this example http://jsfiddle.net/igoryan/V4m5K/1/
To do so, you will need to drag the Caption 6 in place of Caption 5. And then press + button on Caption 6. The Caption 6 will move the left list but will also stay in the right list.

I came up with this solution. I just changed this line:
$(arg.sourceParent === arg.targetParent ? this : ui.sender).sortable('cancel');
to

sourceParent.remove(item);
sourceParent.splice(arg.sourceIndex, 0, item);
ko.utils.domData.set(el, ITEMKEY, null);
ui.item.remove();

So i basically force the UI to redraw the item by removing/adding the object from array and deleting the previous UI element - that's what your plug in does when the item is allowed to drop.

The same example with fix applied : http://jsfiddle.net/igoryan/JpJYH/8/

Regards,
Igor

IE 7 drag to sort but drop w/ no sort (drop back in same position) - leaves z-index and display:none on all items inside <li>.

For IE 7 I had an issue I spent quite a bit of time on. I have something working now, so I am not sure this is an issue but I could certainly see others coming across something similar. I was using ul w/ li's and the li's had some buttons and a span and input. When I was sorting everything worked perfect except when I started dragging an item, but dropped it with no actual sort change. When this occurred everything in the li had display: none (not the li though). My fix works but I cannot explain why.

data-bind="sortable: {data: model, afterMove: saveSort, options: {opacity:.5}}"

^ I added the options{} bit above. opacity seems to solve my issue. Like I said, I cannot explain this. I saw a similar issue here marked as resolved. It showed when I did a search for " ie " < with spaces. Some of this javascript is over my head. I apologize that I cannot help further. If you need anything please let me know. I will keep an eye on this thread for a couple days.

looking through all of the jquery ui sortable docs I found nothing that hooked into drop event when no change was detected in the sort order...

Thanks,
jxmiller

Prevent knockout-sortable from recreating DOM elements

When using knockout-sortable, the element I am dragging has its contents destroyed and recreated in the DOM. This is different behavior than when making the elements sortable using jQuery UI sortable directly, which just moves the element and its contents.

In my scenario, each of my sortable items is a widget that has its own ko viewmodel applied to it via a custom binding. It's expensive (and unnecessary in my case) to have the widget recreated each time the user moves it.

Is there a way to have knockout-sortable leave the item's mark-up untouched after it is moved?

HTML comments in sortable binding makes dragging funny

My html structure is of the form

<ul class="something" data-bind="sortable: { allOptionsHere}">
    <!-- Some 10 lines of comment -->
    <li class="field" data-bind="template: 'someTemplate'"></li>
</ul>

Sortable initializes properly but dragging an element down in list causes elements between initial and final position skip a parent in binding.
e.g.
if elements in template "someTemplate" are $data
and element hierarchy is: $parent[2] > $parent[1] > $parent[0] > $data
after dragging element from position 0 to 4, all elements between 0 & 4 (1,2,3) will have following hierarchy: $parent[2] > $parent[1] > $data

Removing the comment solves the issue.

Setup component.json for Bower and add to repo

Since I saw this issue #41 I figured I should make an issue for adding this to Twitter's Bower package manager, especially since I already forked the project, made the required component.json file and uploaded it to Bower already :D

You can see the file here: https://github.com/Apsu/knockout-sortable/blob/master/component.json and I can request the Bower project remove my package entry (which points at my fork) and either upload yours for you, or you can upload it. Bower is quite easy to use and a fantastic tool, imo.

incompatible with fooArray.destroy(item)

When using the destroy() method instead of remove(), sorting of the remaining items becomes erratic. Depending on the number of items eliminated, dragging items from earlier in the list to slots later in the list will actually cause the items to appear a few slots before the chosen target. It seems as though the "destroyed" items are still counted when computing the destination index. This behavior can be worked around by manually dragging all the items to the top of the list, one by one, at which point, the destroyed items are invisibly hiding at the end of the list where their indices are greater than the last visible item.

example of problem: http://jsfiddle.net/singram/zgEMZ/29/
line: self.person().aliases.remove(data); // works
change to: self.person().aliases.destroy(data); // breaks

global options.options clobbered by binding options.options not individually overriden

If jQuery UI Sortable options are set in ko.bindingHandlers.sortable.options and a (possibly disjoint) set of options are specified in the binding (at the "call site"), the binding options completely override all the global ones, rather than overriding them individually.

For example, these global options:

ko.bindingHandlers.sortable.options = {
    placeholder: 'ui-state-highlight',
    tolerance: 'pointer',
    forcePlaceholderSize: true,
    distance: 20
};

and this tweak at the callsite:

<ul data-bind='sortable: {data: someObsArray, options: {containment: ".modal-body"}}, template: "someTemplate"'></ul>

currently results in the jQuery UI Sortable created by the (awesome!) binding only getting option containment, not the 4 other custom global options. Pull request fixing this to follow.

Create NuGet Package

I would like to see a nuget package for this script. It would require adding an xml file to the source code, and I can setup a build to auto publish from the source once that is in.

live `isEnabled`

It would be great to have a possibility of enabling/disabling a sortable list during the process of sorting another one. I pass isEnabled option with observable in the binding to a sortable <ul> list and want to manipulate it in sort events catched from another sortable <ul> list. Now isEnabled is freezed when sorting begins and is unfreezed only when sorting stops.

All items in a sortable column become draggable; only the parent divs should become draggable

To reproduce data bind using the sortable: binding. In the container that has the sortable: binding create some divs.

Behaves as expected:

<div data-bind="sortable:items">
   <div>item 1</div>
   <div>item 2</div>
</div>

Behaves badly:

<div data-bind="sortable:items">
   <div id="i1">item 1
      <div id="nested_div>nested</div>
   </div>
   <div id="i2">item 2</div>
</div>

In this case the nested_div is also draggable and can be dragged out of its parent.

IMO the expected behaviour is that only the direct children (i1 and i2) should be draggable. I'm fairly sure that this is how the regular jquery sortable works. But I stand to be corrected.

My workaround is to use a jquery :not selector in the options items to exclude the nested items from being draggable.

arg.sourceParentNode is set to the receiver not the sender

Hi and thanks for this great contribution :)

When I am using your library and I log:

 console.log("before Moved '" + arg.item.name() + "' from "
            + arg.sourceParentNode.id 
            + " (index: " + arg.sourceIndex + ") to "
            + event.target.id + " (index " + arg.targetIndex + ")");

for arg.sourceParentNode.id I get the id of the receiving node, not the sending node.

I think the issue is related to code around line165

sourceParentNode: sourceParent && el.parentNode,

If I insert a log stmt after that code like this: console.log("sender", ui.sender)

Then I see the correct sender dom element.

I believe sourceParentNode should be set to ui.sender, or so it seems to me.

In my case, I'm going to use the ui.sender that is passed to my beforeMove handler. But unless I'm misinterpreting the purpose of the arg.sourceParentNode variable then it looks to me that arg.sourceParentNode should in fact be set to ui.sender.

My interpretation of the variables is that I should be able to get a reference to the source's observableArray and dom node, and the target's observableArray and dom node via the arg var. At least for me that would be ideal.

Please advise if I'm misinterpreting something.

Many Thanks,
Matt

Uncaught TypeError: Object [object Object] has no method 'sortable'

Anyone getting this error?

Uncaught TypeError: Object [object Object] has no method 'sortable'
ko.bindingHandlers.sortable.init.controlsDescendantBindings

Just wondering if anyone knows what that means, I get the error but then it still seems to work anyway?

My html looks like:

  • The only things I added to my javascript viewmodel is:

    var Task = function (name) {
    this.name = ko.observable(name);
    };

    viewModel.selectedTask = ko.observable();
    viewModel.clearTask = function () {
        viewModel.selectedTask(null);
    };
    viewModel.selectedProject = ko.observable();
    viewModel.selectedProject.subscribe(function (newValue) {
        newValue.ObjectiveBulletList = ko.observableArray([]);
    
    
        newValue.ObjectiveBulletList.push(new Task("Test"));
    });
    

    Apparently I need to do something else but I'm not sure what I'm missing...

  • There is no way for the connectWith option to be false

    In some case you do not want a connectWith selector to be set (eg. preventing of dragging and dropping of items between levels in a nested list). However, there does not currently seem to be a way to specify connectWith as its default value of false.

    If no connectClass is specified on the plugin then it defaults to .ko_container

    I have hacked the code around so that:

    connectWith: connectClass ? "." + connectClass : false

    and the default connectClass value is null:

    connectClass: null,

    This works for my situation but a more generic method is probably needed.

    Supporting virtual elements ?

    Hi,

    I want to use your sortable binding with virtual elements :

    `


    • Header item


    • Item

    `

    But when I try this, Knockout tell me that the binding doesn't support virtual elements.

    So,

    1. Is it possible to bring the support of virtual elements on the sortable binding (jQueryUI limitation, ko.virtualElements missing function) ?
    2. If yes, do you think that this is representing a great development effort ?

    Thanks,

    Simon Berube

    Does this work on smart phones?

    Does sortable work on mobile / smart phones / iPad etc. I've tried on iPad / Android powered phones without success. I am not able to select individual items. Whenever I tap on one item the whole list gets selected and drag/drop doesn't happen.

    ie8 sortable with template makes items disappear

    In ie8, with the connectedLists lists example. If I drag them around I can make them disappear. I see that in other examples they import jquery-tmpl.js and this fixes it for simple templates.

    ie error -
    Object expected knockout-2.2.0.js, line 38 character 482

    UI and data can get out of sync

    I found this bug while helping someone use sortable (a simpler version) with my deferred updates plugin. Here's how to reproduce (in Chrome, at least):

    1. Open the seating chart example: http://jsfiddle.net/rniemeyer/UdXr4/
    2. Drag Bobby below Ted (but don't drop it) and then put it back.
    3. Drag Jim before Ted (but don't drop it) and put it back.
    4. Drag Bobby and drop it after Ted.
    5. Now the list and data are out of sync. The list says Ted, Jim, Bobby (wrong) and the data says Ted, Bobby, Jim (correct).

    Here's a link to the issue where I discussed this and provided a fix: mbest/knockout-deferred-updates#2

    Question regarding cancelDrop: Perform a request

    I'd like to do a request to a server before I update my model. I can use beforeCancel for that. If I change args.cancelDrop to true the item won't be moved.

    Is there a way to perform an ajax request and wait for the result before leaving the beforeMove function?

    I thought about

    beforeMove = function(args) {
        var xhr = $.ajax({url: 'http://example.com/update/', async: false})
        .fail(function(xhr, text_status) {
            if (xhr.status === 0) { // connection error
                args.cancelDrop = true;
            }
        });
    }
    

    but I know that $.ajax({async:false}) is not waiting for the request to finish.

    Does anyone have a solution for this?

    Keep up the great work, knockout-sortable is awesome!

    Problem with 'dragged' function and receive event.

    Hi, I'm a developer using this lib.

    I had to use 'dragged' function to manipulate the object before dropping to the other sortable list. However:
    First, in receive event function, 'dragItem = dataGet(ui.item[0], DRAGKEY)' doesn't get anything, so later code is ignored. I had to use 'dragItem = dataGet(ui.item[0], ITEMKEY)' to get the object.

    Second, in update event function, 'item = dataGet(el, ITEMKEY) || dragItem;' ignores dragItem when dataGet(el, ITEMKEY) is available. I had to use 'item = dragItem || dataGet(el, ITEMKEY);' to use manipulated object.

    Could someone let me know why I am having this issue? Or is there something I missed? Thanks!

    underlyingArray is undefined on a dynamically-created sortable

    I have a setup very similar to the seating chart example. However, when I create a dynamic sortable "table" (or in my case "user") and drop a student (in my case a "task") from a statically-created sortable it creates the error Uncaught TypeError: Cannot read property 'splice' of undefined.

    This sortable is created for each user in my model (which can be dynamic). I notice that when I drop a task from a pending task to a user (static sortable to dynamic sortable) the underlyingArray for the targetParent is undefined. However when I perform the reverse operation it correctly splices the underlyingArray on pending tasks.

    There are no other errors when the sortable is created, so whatever is missing is going undefined.

    How can I help provide more context and help?

    Sortable gets initialised too early

    $(element).sortable is called before the template contents get a chance to bind. This is problematic when a sortable option is specified. For instance, if I only want to sort items that have a 'valid' class I specify options like this: options: { items: 'li.valid' }. If I apply this valid class to my list elements using a data-bind, this class is not applied when sortable is called.

    This can be trivially fixed by wrapping the call to sortable in a Clock.setTimeout(func, 0); but maybe there's a more elegant fix.

    jQuery Tmpl conflict

    I created a sortable with the following :

    and while using jQuery templates in other view i've got an error :

    Uncaught SyntaxError: Unexpected token & jQuery.tmpl.js:10

    is there any conflict with using Sortable with jQuery Templates ?

    doesn't work properly with virtual element on ko 2.2

    For sortable I use div as container and divs as items. I also tried table and trs. In template I use ko virtual element and if binding to show or hide some content depending on viewModel data. It breaks on knockout.2.2.js on line 546 if initial value of property which is bound to 'if' binding is false. Everything works file if initial value is true. I made simple example in jsFiddle.net. Try to change Task's Active to true for both items. It worked with fine with ko 2.1

    http://jsfiddle.net/Shv5t/1/

    Cross-window issues

    When using a single model bound to both the current document and an iframe in it, ie with the following snippet in the iframe:

    var ko = window.parent.ko;
    var model = window.parent.model;
    
    ko.applyBindings(model, document.body);

    Sortable doesn't work correctly, if you try to grab a sortable item in the iframe it won't move until you move the mouse outside of the iframe. Similar to the issue described on stackoverflow. The issue being that knockout will use the jquery(ui) object of the parent window to create the sortable even though the element upon which it's called is in another document.

    Currently to solve this issue i've slightly modified knockout-sortable.js slightly to make it work but that solution is not ideal:

         //connect items with observableArrays
         ko.bindingHandlers.sortable = {
             init: function(element, valueAccessor, allBindingsAccessor, data, context) {
    -            var $element = $(element),
    +            var ownerWindow = (element.ownerDocument.defaultView || element.ownerDocument.parentWindow);
    +            var jQuery = ownerWindow.jQuery || $;
    +
    +            var $element = jQuery(element),
                     value = unwrap(valueAccessor()) || {},
                     templateOptions = prepareTemplateOptions(valueAccessor, "foreach"),
                     sortable = {},

    No option to clone\copy an item.

    hi,
    its not an issue but an add on that is required in my case .
    i want to copy the an item instead of moving . i following you "seating chart"
    http://jsfiddle.net/rniemeyer/UdXr4/
    post in my requirement i want to copy the students (available students) in to different places (groups)
    a sudent can be associated with multiple groups but each group must have distinct student.

    also in the ""available students list""all ungrouped students (those who do not belong to any group are coloured as red)

    please help me out to do this and provide an updated sample.
    Thanks!!

    Falsey values not handled properly

    Issue #50 fixed support for non-objects (an observableArray of strings, for example). However, there is logic that checks for the falsiness of certain values, which causes failures if the array item is 0, null, undefined, NaN, or "".

    How do you access a mapped sourceParent?

    Thought I had found all of the caveats, but maybe this is a limitation of mapping ;)

    In your seating chart example you have arg.targetParent.id. However, what if that ID of the target parent was mapped using the mapping plugin?

    I tried multiple methods to access it but the common error was cannot access __ko_mapping__ of undefined. http://jsfiddle.net/DeLongey/F782z/

    Do I write my own handlers for this?

    'out' event won't fire when 2 similar sortables are on the same page

    See here

    http://jsfiddle.net/eyG3A/

    Everything but the 'out' event seems to fire normally, but it seems to have really buggy behavior when there are multiple sortables on similarly structured data at the same time.

    To reproduce, try dragging an item from one of the lists away from both lists (not into the other list). 'out' won't fire. Then remove one of the unordered lists and rerun. It will fire normally.

    JqueryUI 1.10.3 issue

    It appears there is an issue with this plugin and the latest version of JqueryUI. If the user attempts to move an item to the end of a different list it tries to put the item as the second to last. See this fiddle for an example. The issue is easiest to see if you drag an item down towards the bottom of its current list before dragging to the other list. The issue only seems to occur on the first drag into the area, if you drag outside of the other list then back it seems to work as expected.

    capture The red arrow is where the item will be inserted when the mouse is released, the blue arrow is where it should actually go.

    Having a condition inside the sortable item template that can exclude the item creates error

    See http://jsfiddle.net/unklefolk/VQndj/ based on the simple example.

    The condition:

    ko if: $data.Name !== 'Fix car'

    .. causes a certain item to be excluded. However, this causes an error:

    Uncaught TypeError: Cannot read property '__ko__1332343640095' of null

    This is because in afterRender, element.parentNode is null.

        afterRender: function (elements, data) {
            ko.utils.arrayForEach(elements, function (element) {
                if (element.nodeType === 1) {
                    ko.utils.domData.set(element, itemKey, data);
                    ko.utils.domData.set(element, parentKey, ko.utils.domData.get(element.parentNode, listKey));
                }
            });
        },
    

    The following seems to fix the error but not sure if this is the correct fix:

        afterRender: function (elements, data) {
            ko.utils.arrayForEach(elements, function (element) {
                if (element.nodeType === 1 && element.parentNode) {
                    ko.utils.domData.set(element, itemKey, data);
                    ko.utils.domData.set(element, parentKey, ko.utils.domData.get(element.parentNode, listKey));
                }
            });
        },
    

    afterRender can't be easily globally customized

    The "default"/base global definition of ko.bindingHandlers.sortable.afterRender contains important functionality for this custom binding widget that shouldn't be blindly clobbered, but rather should be done like this

        var baseAfterRender = ko.bindingHandlers.sortable.afterRender;
        ko.bindingHandlers.sortable.afterRender = function(elements, data) {
            // execute "base" functionality
            baseAfterRender.call(data, elements, data);
            // start custom functionality...
            elements = $(elements).filter("li");
            elements.removeClass('ui-state-hover');
            elements.mouseover(function() {
                $(this).addClass('ui-state-hover');
            });
            elements.mouseout(function() {
                $(this).removeClass('ui-state-hover');
            });
        };

    The template binding customization method doesn't have this issue. It would be cool if this pitfall wasn't there - maybe a "private" _afterRender and the global and/or options afterRender callbacks are optional (and called after _afterRender).

    The documentation mentions afterRender only once

    afterAdd, beforeRemove, afterRender, includeDestroyed, templateEngine - this binding will pass these options on to the template binding.

    However, afterRender is not referenced in function prepareTemplateOptions (afterAdd is). Is something wrong there? (i.e., afterRemove missing from that array?

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google โค๏ธ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.