a5hik/ng-sortable

Using the `accept` function is not so easy (placeholderIndex value is missing from the parameters).

Opened this issue · 1 comments

I have a list of dragables and some of them are disabled and I allow no drop on them.
I am using the accept function like so:

        accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
            var ix = destItemScope && destItemScope.index && destItemScope.index(),
                curr = $scope.items[ix];

            if (curr && curr.isSeparator) return false;
            return true;
        },

The issue is that, the ix and curr do not help me understand if the drop placeholder will be placed before or after the curr element. And it appears that it can be either of those.

Am I missing something?
Is there a way to find the items between which the drop placeholder will be placed?
I haven't managed to achieve this in my case.

UPDATE:

I think this is what is missing:

image

The placeholderIndex should be inserted in target or the sortable scope.
Do you accept PRs for this?

For your info, I have fixed that like so:
I have replaced this:

              if (targetScope.type === 'item' && targetScope.accept(scope, targetScope.sortableScope, targetScope)) {
                // decide where to insert placeholder based on target element and current placeholder if is present
                targetElement = targetScope.element;

                // Fix #241 Drag and drop have trembling with blocks of different size
                var targetElementOffset = $helper.offset(targetElement, scrollableContainer);
                if (!dragItemInfo.canMove(itemPosition, targetElement, targetElementOffset)) {
                  return;
                }

                var placeholderIndex = placeHolderIndex(targetScope.sortableScope.element);
                if (placeholderIndex < 0) {
                  insertBefore(targetElement, targetScope);
                } else {
                  if (placeholderIndex <= targetScope.index()) {
                    insertAfter(targetElement, targetScope);
                  } else {
                    insertBefore(targetElement, targetScope);
                  }
                }
              }

...with this (passing the ix into the accept function - I have also updated the proxy call to accept to handle another parameter):

            if (targetScope.type === 'item') {
                // decide where to insert placeholder based on target element and current placeholder if is present
                targetElement = targetScope.element;

                // Fix #241 Drag and drop have trembling with blocks of different size
                var targetElementOffset = $helper.offset(targetElement, scrollableContainer);
                if (!dragItemInfo.canMove(itemPosition, targetElement, targetElementOffset)) {
                    return;
                }

                var ix = targetScope.index();
                var placeholderIndex = placeHolderIndex(targetScope.sortableScope.element);
                if (dragItemInfo.isSameParent() && !dragItemInfo.sourceInfo.sortableScope.cloning) {
                    if (dragItemInfo.source.index() < ix) {
                        ix = ix - 1;
                    } else {
                        ix = ix - 1;
                    }
                }

                if (placeholderIndex < 0 || placeholderIndex > ix) {
                    if (targetScope.accept(scope, targetScope.sortableScope, targetScope, ix))
                        insertBefore(targetElement, targetScope);
                } else {
                    ix++;
                    if (targetScope.accept(scope, targetScope.sortableScope, targetScope, ix))
                        insertAfter(targetElement, targetScope);
                }
            }

If you want, merge it in.
I certainly find it extremely useful to get this extra ix variable.

Cheers.