Skip to content

Items added after initializing list with maxLevels cannot be dragged #68

@lucaslm

Description

@lucaslm

Greetings again @camohub!

I've noticed an issue that appeared in this new version 2.2.0.
Whenever we have a sortable list initialized with some value for maxLevels, any new item that is later appended to the list cannot be dragged into a new position.
I've set an example on my forking so you can see for yourself:

https://lucaslm.github.io/jquery-sortable-lists/example3

The reason for this error is because you changed how to compute the level an item would have when dragged to a new position. Specifically, upon initializing the list you add some data to every item, namely 'inside-levels' and 'upper-levels'.

if( setting.maxLevels !== false )
{
if( isNaN( setting.maxLevels ) ) throw 'JQuery-sortable-lists maxLevels values is not a number';
$( this ).find( 'li' ).each( function()
{
var insideLevs = getInsideLevels( $(this) );
var upperLevs = getUpperLevels( $(this) );
setInsideLevels( $(this), insideLevs );
setUpperLevels( $(this), upperLevs );
});
}

Later on the function checkMaxLevels, you get 'upper-levels' from the new parent and 'inside-levels' from the item being dragged. You then add those to see if it exceeds maxLevels. Since items created later do not have 'inside-levels', the sum evaluates to NaN and the expression to false, even when it shouldn't.

function checkMaxLevels( inside )
{
var insideLevs = state.cEl.el.data( 'inside-levels' );
var upperLevs = state.oEl.data( 'upper-levels' );
return setting.maxLevels > upperLevs + insideLevs + (inside ? 1 : 0);
}

This can be avoided if you do not insert new items, but it wasn't an issue when insideLevs was computed at startDrag for the item being dragged, and upperLevs at its dropping, though it could be less performatic.

I suppose there are two approaches for this. We can create a new option to control how maxLevels is computed, to let the user choose whether to compute the levels on the fly ineficiently (but allowing later item insertions) or to store the levels on initialization. The other approach is to use a MutationObserver to store an item's levels each time it is included on the list's DOM after initialization.

Let me know which approach you think is best, and I can create a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions