9

My list allows moving child items out of parent item, and I want to change it.

enter image description here

As you can see, moving child items from inside of parent to another parent should be allowed, but moving child items outside of any parent item should not be allowed.

I think the code would be too long, so here is the nestable list similiar to that I'm using nestableList from Luna theme, and here is the script jquery.nestable.js

Denis Wasilew
  • 503
  • 3
  • 9
  • 29

3 Answers3

5

Note 1 before reading this answer refer to the other answer, it is really useful and helped me a lot. Note 2 as that answer said, and the author of the original library, that library is completely dead. But there is somebody which take the responsibility of continuing developing this library, here is the new library
Note 3 even the new library will not support rejecting rules, and you still have to use a pull request of the library.

I had EXACTLY the same case of the asker (and that what make me reaching here). Here is how I solved my problem (and I hope this will help others)

Answer

HTML

<div class="dd" id="nestable-example">
    <ol class="dd-list">

        <li class="dd-item" data-id="0" data-type="root">
            <div class="dd-handle">Root 0</div>
            <ol class="dd-list">
                <li class="dd-item" data-id="1" data-type="child">
                    <div class="dd-handle">Child 1</div>
                </li>
                <li class="dd-item" data-id="2" data-type="child">
                    <div class="dd-handle">Child 2</div>
                </li>
                <li class="dd-item" data-id="3" data-type="child">
                    <div class="dd-handle">Child 2</div>
                </li>
            </ol>
        </li>

        <li class="dd-item" data-id="4" data-type="root">
            <div class="dd-handle">Root 4</div>
            <ol class="dd-list">
                <li class="dd-item" data-id="5" data-type="child">
                    <div class="dd-handle">Child 5</div>
                </li>
                <li class="dd-item" data-id="6" data-type="child">
                    <div class="dd-handle">Child 6</div>
                </li>
            </ol>
        </li>

    </ol>
</div>

JavaScript

$('#nestable-example').nestable({
    group: 'categories', // you can change this name as you like
    maxDepth: 2,   // this is important if you have the same case of the question
    reject: [{
        rule: function () {
            // The this object refers to dragRootEl i.e. the dragged element.
            // The drag action is cancelled if this function returns true
            var ils = $(this).find('>ol.dd-list > li.dd-item');
            for (var i = 0; i < ils.length; i++) {
                var datatype = $(ils[i]).data('type');
                if (datatype === 'child')
                    return true;
            }
            return false;
        },
        action: function (nestable) {
            // This optional function defines what to do when such a rule applies. The this object still refers to the dragged element,
            // and nestable is, well, the nestable root element
            alert('Can not move this item to the root');
        }
    }]
});
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
  • Very Goood. Thank you `group: 'categories',maxDepth: 2` work for me. – Milad Ghiravani Jan 16 '18 at 11:06
  • Please, can you tell which Pull Request did you use to achieve this reject behavior? I did not find it. Thanks! – Laerte Jul 24 '18 at 20:20
  • He meant this pull request: [link](https://github.com/dbushell/Nestable/pull/85) – marmite Feb 17 '20 at 09:51
  • reject is not working in my code, I am using nestable2. I want to prevent the child node not to move in another parent node. It should only be dragged in its parent group. Please suggest any help. @hakan – Nayan Hodar Jun 29 '20 at 10:16
  • You can answer here: https://stackoverflow.com/questions/62636340/nestable2-how-to-prevent-child-node-to-dragged-in-another-parent-node – Nayan Hodar Jun 29 '20 at 10:41
4

In the example you provided, the jQuery plugin used is Nestable from dbushell. Do you have any control over the plugin you'll end up using ? The project is completely dead and has not been updated for 2 years.

It could be wise to maybe check for a solution still maintained and proposing your feature which is pretty much a 'protectRoot' feature that many libraries have nowadays.

If you have no control over the plugin, this feature at the moment is not implemented and will probably never be.

If you have control over the plugin but still want to use this one, a solution could be to use a fork (there are many since the project is dead) still maintained and having this feature.

Another solution would be to cherry pick yourself code you're interested in from the many pull requests submitted to the project but that will never be merged.

For example, this pull request add new callbacks instead of the only one available at the moment: beforeDragStart, dragStart, dragMove, beforeDragEnd, dragEnd, etc. These new callbacks provides many arguments like the item you're currently moving, where it was before you started dragging it, and the destination. Based on these new informations and especially the destination, you could cancel the drag if the destination a root node.

$('.dd').nestable({})
.on('dragMove', function(event, item, source, destination) {
    // item: item we're moving.
    // source: original source of the item.
    // destination: new position of the item.
});

Another pull request that could suits your needs is this one. It provides callback to reject specific drag event, you could for example reject a drag event if the item being dragged becomes a root element.

$('.dd').nestable({
  reject: [
    {
      rule: function() { 
        // $(this) refers to the dragged element. 
        // Return TRUE to cancel the drag action.

        return $(this).parent().hasClass("rootList");
      }
    }
  ]
});
HiDeoo
  • 10,353
  • 8
  • 47
  • 47
  • Uhm... stil lhard to understand it. I'm not very used to js, and don' really know how to do it. I wiill take time and will try to understand what is going on in these pull requests. Thanks for the hints anyway – Denis Wasilew Jul 16 '16 at 15:05
  • Well basically, it's new code (from the community) implementing missing features in a dead project. If you want to stick with it and test this pull requests, check any tutorial regarding how to apply them, it's not that difficult and you'll be good to go. – HiDeoo Jul 16 '16 at 15:09
  • 1
    @HiDeo, The problem is, all these events get fired after the change event. So even if I cancel the event, the reorder will happen. How Can I stop the reorder from happing. – user123456 Oct 24 '16 at 12:46
2

I can't figure out a good solution with all the nestable pull requests and nestable itself. I came across this extension for jQuery-UI sortable. Here you have the property protectRoot. This works great. Example code:

HTML

<ol class="sortable">
    <li><div>Some content</div></li>
    <li>
        <div>Some content</div>
        <ol>
            <li><div>Some sub-item content</div></li>
            <li><div>Some sub-item content</div></li>
        </ol>
    </li>
    <li><div>Some content</div></li>
</ol>

Javascript

$('.sortable').nestedSortable({
    handle: 'div',
    items: 'li',
    toleranceElement: '> div',
    protectRoot: true,
    maxLevels: 2
});
Yetispapa
  • 2,174
  • 2
  • 30
  • 52