4

EDIT 3: Just to summarize what became quite a long question in the hope that someone might find it easier to get the gist of it and be able to help more easily:

What I want is to get the jsfiddle # 2 below (under EDIT 2) to work, in the sense that it should correctly drop multiple items in the right place, when selected and dragged.

Original question:

I'm trying to figure out how to make nestedSortable allow multiple items to be selected. I cannot find any information about it anywhere by Googling, and I cannot figure it out myself.

If anyone knows how to do this, that would be great. I have been looking at this as an example of how to get drag and drop with multiple items to work - this was hard to find in itself!

jsfiddle #1, multi-select with drag and drop but only in a flat element structure: http://jsfiddle.net/2n9xkmg3/

Main jQuery code here:

$(function () {
    $('.droptrue').on('click', 'li', function () {
        $(this).toggleClass('selected');
    });

    $("ul.droptrue").sortable({
        connectWith: 'ul.droptrue',
        opacity: 0.6,
        revert: true,
        helper: function (e, item) {
            console.log('parent-helper');
            console.log(item);
            if(!item.hasClass('selected'))
               item.addClass('selected');
            var elements = $('.selected').not('.ui-sortable-placeholder').clone();
            var helper = $('<ul/>');
            item.siblings('.selected').addClass('hidden');
            return helper.append(elements);
        },
        start: function (e, ui) {
            var elements = ui.item.siblings('.selected.hidden').not('.ui-sortable-placeholder');
            ui.item.data('items', elements);
        },
        receive: function (e, ui) {
            ui.item.before(ui.item.data('items'));
        },
        stop: function (e, ui) {
            ui.item.siblings('.selected').removeClass('hidden');
            $('.selected').removeClass('selected');
        },
        update: updatePostOrder
    });

    $("#sortable1, #sortable2").disableSelection();
    $("#sortable1, #sortable2").css('minHeight', $("#sortable1").height() + "px");
    updatePostOrder();
});

function updatePostOrder() {
    var arr = [];
    $("#sortable2 li").each(function () {
        arr.push($(this).attr('id'));
    });
    $('#postOrder').val(arr.join(','));
}

The suggestion for that example I found in a comment in another Stack overflow question:

How do I drag multiple elements at once with JavaScript or jQuery?

So how could I make that multi-select work in nestedSortable plugin?

See https://github.com/ilikenwf/nestedSortable for information about that plugin.

Basically what I want to achieve is dragging and dropping of items (like files and folders, but could be other things too) in a web application, similar to what DropBox and Google Drive has with multiple dragging and dropping of files and folders in their web interfaces.

Except...I need this with the nesting like in the nestedSortable plugin.

Since so many web sites have functionality like that, I pretty much thought there would be a ready-made solution out there, but it has proven remarkably hard to find an answer to even the flat structure dragging and dropping of multiple items, let alone the combination with the nested structure. But there are quite a few of those examples in various web sites too, I just don't know how to achieve it.

Any help greatly appreciated!

EDIT: added the link to the plugin above.

EDIT 2:

I felt like the question needed a much more clear example in order to get help on this issue. So I created a full jsfiddle of my own.

This one takes the jsfiddle referred to above and I have then tried to create a new one, based on the nestedSortable plugin example file: https://github.com/ilikenwf/nestedSortable/blob/2.0alpha/example.html

Here is my new jsfiddle:

jsfiddle #2, ATTEMPT at multi-select with drag and drop in a nested structure:

http://jsfiddle.net/anderszvensson/w141dLLt/1/

I started with that example of a nested sortable list. Then I tried to incorporate the multi-select from the jsfiddle #1 (the one that only handles multi-select drag and drop for flat structures).

The parts I have incorporated so far are only the toggleClass for .selected on the <li> elements, also adding a border for when an <li> is selected, and the helper option.

This does make it work in part, but not completely. That is, dragging multiple elements shows that it does bring all the selected elements in the dragging.

However, only one of the elements is still dropped/received. I am not able to get it to actually move/drop all the elements in the drag.

I hope this helps, so that someone better than me at jQuery could figure out how to make the drag and drop of multiple elements work in this nestedSortable plugin.

For clarity, here is the code from jsfiddle #2 (my own attempt):

HTML:

<body>
    <header>
        <h1>nestedSortable jQuery Plugin</h1>

        <h2>2.0</h2>
    </header>

    <section>
        <p>This is the demo page for the nestedSortable jQuery plugin.</p>

        <p><strong>Follow the development, read the docs and download the
        latest version directly from the <a href="https://github.com/ilikenwf/nestedSortable">GitHub
        page</a>.</strong></p>
    </section><!-- END section -->

    <section id="demo">
        <ol class="sortable ui-sortable mjs-nestedSortable-branch mjs-nestedSortable-expanded">
           <li style="display: list-item;" class="mjs-nestedSortable-branch mjs-nestedSortable-expanded" id="menuItem_2">
           <div class="menuDiv">
               <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
               <span></span>
               </span>
               <span title="Click to show/hide item editor" data-id="2" class="expandEditor ui-icon ui-icon-triangle-1-n">
               <span></span>
               </span>
               <span>
               <span data-id="2" class="itemTitle">a</span>
               <span title="Click to delete item." data-id="2" class="deleteMenu ui-icon ui-icon-closethick">
               <span></span>
               </span>
               </span>
               <div id="menuEdit2" class="menuEdit hidden">
                   <p>
                       Content or form, or nothing here. Whatever you want.
                   </p>
               </div>
           </div>
           <ol>
               <li style="display: list-item;" class="mjs-nestedSortable-branch mjs-nestedSortable-expanded" id="menuItem_4">
               <div class="menuDiv">
                   <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
                   <span></span>
                   </span>
                   <span title="Click to show/hide item editor" data-id="4" class="expandEditor ui-icon ui-icon-triangle-1-n">
                   <span></span>
                   </span>
                   <span>
                   <span data-id="4" class="itemTitle">c</span>
                   <span title="Click to delete item." data-id="4" class="deleteMenu ui-icon ui-icon-closethick">
                   <span></span>
                   </span>
                   </span>
                   <div id="menuEdit4" class="menuEdit hidden">
                       <p>
                           Content or form, or nothing here. Whatever you want.
                       </p>
                   </div>
               </div>
               <ol>
                   <li class="mjs-nestedSortable-leaf" id="menuItem_6">
                   <div class="menuDiv">
                       <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
                       <span></span>
                       </span>
                       <span title="Click to show/hide item editor" data-id="6" class="expandEditor ui-icon ui-icon-triangle-1-n">
                       <span></span>
                       </span>
                       <span>
                       <span data-id="6" class="itemTitle">e</span>
                       <span title="Click to delete item." data-id="6" class="deleteMenu ui-icon ui-icon-closethick">
                       <span></span>
                       </span>
                       </span>
                       <div id="menuEdit6" class="menuEdit hidden">
                           <p>
                               Content or form, or nothing here. Whatever you want.
                           </p>
                       </div>
                   </div>
                   </li>
               </ol>
               </li>
               <li style="display: list-item;" class="mjs-nestedSortable-leaf" id="menuItem_5">
               <div class="menuDiv">
                   <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
                   <span></span>
                   </span>
                   <span title="Click to show/hide item editor" data-id="5" class="expandEditor ui-icon ui-icon-triangle-1-n">
                   <span></span>
                   </span>
                   <span>
                   <span data-id="5" class="itemTitle">d</span>
                   <span title="Click to delete item." data-id="5" class="deleteMenu ui-icon ui-icon-closethick">
                   <span></span>
                   </span>
                   </span>
                   <div id="menuEdit5" class="menuEdit hidden">
                       <p>
                           Content or form, or nothing here. Whatever you want.
                       </p>
                   </div>
               </div>
               </li>
           </ol>
           </li>
           <ol>
           </ol>
           <li style="display: list-item;" class="mjs-nestedSortable-leaf" id="menuItem_7">
           <div class="menuDiv">
               <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
               <span></span>
               </span>
               <span title="Click to show/hide item editor" data-id="7" class="expandEditor ui-icon ui-icon-triangle-1-n">
               <span></span>
               </span>
               <span>
               <span data-id="7" class="itemTitle">f</span>
               <span title="Click to delete item." data-id="7" class="deleteMenu ui-icon ui-icon-closethick">
               <span></span>
               </span>
               </span>
               <div id="menuEdit7" class="menuEdit hidden">
                   <p>
                      Content or form, or nothing here. Whatever you want.
                   </p>
               </div>
           </div>
           </li>
           <li class="mjs-nestedSortable-leaf" id="menuItem_3">
           <div class="menuDiv">
               <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
               <span></span>
               </span>
               <span title="Click to show/hide item editor" data-id="3" class="expandEditor ui-icon ui-icon-triangle-1-n">
               <span></span>
               </span>
               <span>
               <span data-id="3" class="itemTitle">b</span>
               <span title="Click to delete item." data-id="3" class="deleteMenu ui-icon ui-icon-closethick">
               <span></span>
               </span>
               </span>
               <div id="menuEdit3" class="menuEdit hidden">
                   <p>
                       Content or form, or nothing here. Whatever you want.
                   </p>
               </div>
           </div>
           </li>
       </ol>

        <h3>Try the custom methods:</h3>

        <p><br>
        <input id="serialize" name="serialize" type="submit" value=
        "Serialize"></p>
        <pre id="serializeOutput">
        </pre>

        <p><input id="toArray" name="toArray" type="submit" value=
        "To array"></p>
        <pre id="toArrayOutput">
        </pre>

        <p><input id="toHierarchy" name="toHierarchy" type="submit" value=
        "To hierarchy"></p>
        <pre id="toHierarchyOutput">
        </pre>

        <p><em>Note: This demo has the <code>maxLevels</code> option set to '4'.</em></p>
    </section><!-- END #demo -->

    <section id="license">
        <h4>License</h4>

        <p>This work is licensed under the MIT License.<br>
        Which means you can do pretty much whatever you want with it.</p>

        <p>&copy; 2010&dash;2014 Manuele J Sarfatti</p>
    </section><!-- END #documentation -->
</body>

JS:

$().ready(function(){
            $('li.mjs-nestedSortable-leaf').on('click', function () {               
                $(this).toggleClass('selected');
            });
            var ns = $('ol.sortable').nestedSortable({
                forcePlaceholderSize: true,
                handle: 'div',
                helper: function (e, item) {
                    console.log('parent-helper');
                    console.log(item);
                    if(!item.hasClass('selected'))
                       item.addClass('selected');
                    var elements = $('.selected').not('.ui-sortable-placeholder').clone();
                    var helper = $('<ul/>');
                    item.siblings('.selected').addClass('hidden');
                    return helper.append(elements);
                    },
                start: function (e, ui) {
                    var elements = ui.item.siblings('.selected.hidden').not('.ui-sortable-placeholder');
                    ui.item.data('items', elements);
                },
                receive: function (e, ui) {
                    ui.item.before(ui.item.data('items'));
                },
                stop: function (e, ui) {
                    ui.item.siblings('.selected').removeClass('hidden');
                    $('.selected').removeClass('selected');
                },                  
                items: 'li',
                opacity: .6,
                placeholder: 'placeholder',
                revert: 250,
                tabSize: 25,
                tolerance: 'pointer',
                toleranceElement: '> div',
                maxLevels: 4,
                isTree: true,
                expandOnHover: 700,
                startCollapsed: false,
                change: function(){
                    console.log('Relocated item');
                }
            });

            $('.expandEditor').attr('title','Click to show/hide item editor');
            $('.disclose').attr('title','Click to show/hide children');
            $('.deleteMenu').attr('title', 'Click to delete item.');

            $('.disclose').on('click', function() {
                $(this).closest('li').toggleClass('mjs-nestedSortable-collapsed').toggleClass('mjs-nestedSortable-expanded');
                $(this).toggleClass('ui-icon-plusthick').toggleClass('ui-icon-minusthick');
            });

            $('.expandEditor, .itemTitle').click(function(){
                var id = $(this).attr('data-id');
                $('#menuEdit'+id).toggle();
                $(this).toggleClass('ui-icon-triangle-1-n').toggleClass('ui-icon-triangle-1-s');
            });

            $('.deleteMenu').click(function(){
                var id = $(this).attr('data-id');
                $('#menuItem_'+id).remove();
            });

            $('#serialize').click(function(){
                serialized = $('ol.sortable').nestedSortable('serialize');
                $('#serializeOutput').text(serialized+'\n\n');
            })

            $('#toHierarchy').click(function(e){
                hiered = $('ol.sortable').nestedSortable('toHierarchy', {startDepthCount: 0});
                hiered = dump(hiered);
                (typeof($('#toHierarchyOutput')[0].textContent) != 'undefined') ?
                $('#toHierarchyOutput')[0].textContent = hiered : $('#toHierarchyOutput')[0].innerText = hiered;
            })

            $('#toArray').click(function(e){
                arraied = $('ol.sortable').nestedSortable('toArray', {startDepthCount: 0});
                arraied = dump(arraied);
                (typeof($('#toArrayOutput')[0].textContent) != 'undefined') ?
                $('#toArrayOutput')[0].textContent = arraied : $('#toArrayOutput')[0].innerText = arraied;
            });
        });         

        function dump(arr,level) {
            var dumped_text = "";
            if(!level) level = 0;

            //The padding given at the beginning of the line.
            var level_padding = "";
            for(var j=0;j<level+1;j++) level_padding += "    ";

            if(typeof(arr) == 'object') { //Array/Hashes/Objects
                for(var item in arr) {
                    var value = arr[item];

                    if(typeof(value) == 'object') { //If it is an array,
                        dumped_text += level_padding + "'" + item + "' ...\n";
                        dumped_text += dump(value,level+1);
                    } else {
                        dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                    }
                }
            } else { //Strings/Chars/Numbers etc.
                dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
            }
            return dumped_text;
        }

CSS:

html {
            background-color: #eee;
        }

        body {
            -webkit-border-radius: 10px;
            -moz-border-radius: 10px;
            border-radius: 10px;
            color: #444;
            background-color: #fff;
            font-size: 13px;
            font-family: Freesans, sans-serif;
            padding: 2em 4em;
            width: 860px;
            margin: 15px auto;
            box-shadow: 1px 1px 8px #444;
            -mox-box-shadow: 1px 1px 8px #444;
            -webkit-box-shadow: 1px -1px 8px #444;
        }

        a,a:visited {
            color: #4183C4;
            text-decoration: none;
        }

        a:hover {
            text-decoration: underline;
        }

        pre,code {
            font-size: 12px;
        }

        pre {
            width: 100%;
            overflow: auto;
        }

        small {
            font-size: 90%;
        }

        small code {
            font-size: 11px;
        }

        .placeholder {
            outline: 1px dashed #4183C4;
        }

        .mjs-nestedSortable-error {
            background: #fbe3e4;
            border-color: transparent;
        }

        #tree {
            width: 550px;
            margin: 0;
        }

        ol {
            max-width: 450px;
            padding-left: 25px;
        }

        ol.sortable,ol.sortable ol {
            list-style-type: none;
        }

        .sortable li div {
            border: 1px solid #d4d4d4;
            -webkit-border-radius: 3px;
            -moz-border-radius: 3px;
            border-radius: 3px;
            cursor: move;
            border-color: #D4D4D4 #D4D4D4 #BCBCBC;
            margin: 0;
            padding: 3px;
        }

        li.mjs-nestedSortable-collapsed.mjs-nestedSortable-hovering div {
            border-color: #999;
        }

        .disclose, .expandEditor {
            cursor: pointer;
            width: 20px;
            display: none;
        }

        .sortable li.mjs-nestedSortable-collapsed > ol {
            display: none;
        }

        .sortable li.mjs-nestedSortable-branch > div > .disclose {
            display: inline-block;
        }

        .sortable span.ui-icon {
            display: inline-block;
            margin: 0;
            padding: 0;
        }

        .menuDiv {
            background: #EBEBEB;
        }

        .menuEdit {
            background: #FFF;
        }

        .itemTitle {
            vertical-align: middle;
            cursor: pointer;
        }

        .deleteMenu {
            float: right;
            cursor: pointer;
        }

        h1 {
            font-size: 2em;
            margin-bottom: 0;
        }

        h2 {
            font-size: 1.2em;
            font-weight: 400;
            font-style: italic;
            margin-top: .2em;
            margin-bottom: 1.5em;
        }

        h3 {
            font-size: 1em;
            margin: 1em 0 .3em;
        }

        p,ol,ul,pre,form {
            margin-top: 0;
            margin-bottom: 1em;
        }

        dl {
            margin: 0;
        }

        dd {
            margin: 0;
            padding: 0 0 0 1.5em;
        }

        code {
            background: #e5e5e5;
        }

        input {
            vertical-align: text-bottom;
        }

        .notice {
            color: #c33;
        }

        .selected { 
            border: solid #000 1px;
        }
Community
  • 1
  • 1
Anders
  • 12,556
  • 24
  • 104
  • 151

2 Answers2

4

This might help you. If you want to see Fiddle nestedSortable working drag(multiple selected and molested child) and drop in to out of box.

$().ready(function() {
  $('li').on('click', function(e) {
    e.stopPropagation();
    $(this).toggleClass('selected');
  });
  var ns = $('ol.sortable, ol.moved').nestedSortable({

    connectWith: 'ol.moved, ol.sortable',

    forcePlaceholderSize: true,
    handle: 'div',
    helper: function(e, item) {
      console.log('parent-helper');
      console.log(item);
      if (!item.hasClass('selected'))
        item.addClass('selected');
      var elements = $('.selected').not('.ui-sortable-placeholder').clone();
      var helper = $('<ul/>');
      item.siblings('.selected').addClass('hidden');
      return helper.append(elements);
    },
    start: function(e, ui) {
      var elements = ui.item.siblings('.selected.hidden').not('.ui-sortable-placeholder');
      ui.item.data('items', elements);
    },
    receive: function(e, ui) {
      ui.item.before(ui.item.data('items'));
    },
    stop: function(e, ui) {
      ui.item.siblings('.selected').removeClass('hidden');
      $('.selected').removeClass('selected');
    },
    items: 'li',
    opacity: .6,
    placeholder: 'placeholder',
    revert: 250,
    tabSize: 25,
    tolerance: 'pointer',
    toleranceElement: '> div',
    maxLevels: 4,
    isTree: true,
    expandOnHover: 700,
    startCollapsed: false,
    change: function() {
      console.log('Relocated item');
    }
  });

  $('.expandEditor').attr('title', 'Click to show/hide item editor');
  $('.disclose').attr('title', 'Click to show/hide children');
  $('.deleteMenu').attr('title', 'Click to delete item.');

  $('.disclose').on('click', function() {
    $(this).closest('li').toggleClass('mjs-nestedSortable-collapsed').toggleClass('mjs-nestedSortable-expanded');
    $(this).toggleClass('ui-icon-plusthick').toggleClass('ui-icon-minusthick');
  });

  $('.expandEditor, .itemTitle').click(function() {
    var id = $(this).attr('data-id');
    $('#menuEdit' + id).toggle();
    $(this).toggleClass('ui-icon-triangle-1-n').toggleClass('ui-icon-triangle-1-s');
  });

  $('.deleteMenu').click(function() {
    var id = $(this).attr('data-id');
    $('#menuItem_' + id).remove();
  });

  $('#serialize').click(function() {
    serialized = $('ol.moved').nestedSortable('serialize');
    $('#serializeOutput').text(serialized + '\n\n');
  })

  $('#toHierarchy').click(function(e) {
    hiered = $('ol.moved').nestedSortable('toHierarchy', {
      startDepthCount: 0
    });
    hiered = dump(hiered);
    (typeof($('#toHierarchyOutput')[0].textContent) != 'undefined') ?
    $('#toHierarchyOutput')[0].textContent = hiered: $('#toHierarchyOutput')[0].innerText = hiered;
  })

  $('#toArray').click(function(e) {
    arraied = $('ol.moved').nestedSortable('toArray', {
      startDepthCount: 0
    });
    arraied = dump(arraied);
    (typeof($('#toArrayOutput')[0].textContent) != 'undefined') ?
    $('#toArrayOutput')[0].textContent = arraied: $('#toArrayOutput')[0].innerText = arraied;
  });
});

function dump(arr, level) {
  var dumped_text = "";
  if (!level) level = 0;

  //The padding given at the beginning of the line.
  var level_padding = "";
  for (var j = 0; j < level + 1; j++) level_padding += "    ";

  if (typeof(arr) == 'object') { //Array/Hashes/Objects
    for (var item in arr) {
      var value = arr[item];

      if (typeof(value) == 'object') { //If it is an array,
        dumped_text += level_padding + "'" + item + "' ...\n";
        dumped_text += dump(value, level + 1);
      } else {
        dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
      }
    }
  } else { //Strings/Chars/Numbers etc.
    dumped_text = "===>" + arr + "<===(" + typeof(arr) + ")";
  }
  return dumped_text;
}
html {
  background-color: #eee;
}
body {
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  color: #444;
  background-color: #fff;
  font-size: 13px;
  font-family: Freesans, sans-serif;
  padding: 2em 4em;
  width: 860px;
  margin: 15px auto;
  box-shadow: 1px 1px 8px #444;
  -mox-box-shadow: 1px 1px 8px #444;
  -webkit-box-shadow: 1px -1px 8px #444;
}
a,
a:visited {
  color: #4183C4;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
pre,
code {
  font-size: 12px;
}
pre {
  width: 100%;
  overflow: auto;
}
small {
  font-size: 90%;
}
small code {
  font-size: 11px;
}
.placeholder {
  outline: 1px dashed #4183C4;
}
.mjs-nestedSortable-error {
  background: #fbe3e4;
  border-color: transparent;
}
#tree {
  width: 550px;
  margin: 0;
}
ol {
  max-width: 450px;
  padding-left: 25px;
}
ol.moved,
ol.moved ol,
ol.sortable,
ol.sortable ol {
  list-style-type: none;
}
.moved li div,
.sortable li div {
  border: 1px solid #d4d4d4;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  cursor: move;
  border-color: #D4D4D4 #D4D4D4 #BCBCBC;
  margin: 0;
  padding: 3px;
}
li.mjs-nestedSortable-collapsed.mjs-nestedSortable-hovering div {
  border-color: #999;
}
.disclose,
.expandEditor {
  cursor: pointer;
  width: 20px;
  display: none;
}
.moved li.mjs-nestedSortable-collapsed > ol,
.sortable li.mjs-nestedSortable-collapsed > ol {
  display: none;
}
.moved li.mjs-nestedSortable-branch > div > .disclose,
.sortable li.mjs-nestedSortable-branch > div > .disclose {
  display: inline-block;
}
.moved span.ui-icon,
.sortable span.ui-icon {
  display: inline-block;
  margin: 0;
  padding: 0;
}
.menuDiv {
  background: #EBEBEB;
}
.menuEdit {
  background: #FFF;
}
.itemTitle {
  vertical-align: middle;
  cursor: pointer;
}
.deleteMenu {
  float: right;
  cursor: pointer;
}
h1 {
  font-size: 2em;
  margin-bottom: 0;
}
h2 {
  font-size: 1.2em;
  font-weight: 400;
  font-style: italic;
  margin-top: .2em;
  margin-bottom: 1.5em;
}
h3 {
  font-size: 1em;
  margin: 1em 0 .3em;
}
p,
ol,
ul,
pre,
form {
  margin-top: 0;
  margin-bottom: 1em;
}
dl {
  margin: 0;
}
dd {
  margin: 0;
  padding: 0 0 0 1.5em;
}
code {
  background: #e5e5e5;
}
input {
  vertical-align: text-bottom;
}
.notice {
  color: #c33;
}
.selected {
  border: solid #000 1px;
}
ol.sortable,
ol.moved {
  height: 500px;
  float: left;
  width: 46.5%;
}
.selected.hidden {
  display: none !important;
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://ilikenwf.github.io/jquery.mjs.nestedSortable.js"></script>
<header>
  <h1>nestedSortable jQuery Plugin</h1>

  <h2>2.0</h2>
</header>

<section>
  <p>This is the demo page for the nestedSortable jQuery plugin.</p>

  <p><strong>Follow the development, read the docs and download the
        latest version directly from the <a href="https://github.com/ilikenwf/nestedSortable">GitHub
        page</a>.</strong>
  </p>
</section>
<!-- END section -->

<section id="demo">
  <ol class="sortable ui-sortable mjs-nestedSortable-branch mjs-nestedSortable-expanded">

    <li style="display: list-item;" class="mjs-nestedSortable-branch mjs-nestedSortable-expanded" id="menuItem_2">
      <div class="menuDiv">
        <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
               <span></span>
        </span>
        <span title="Click to show/hide item editor" data-id="2" class="expandEditor ui-icon ui-icon-triangle-1-n">
               <span></span>
        </span>
        <span>
               <span data-id="2" class="itemTitle">a</span>
        <span title="Click to delete item." data-id="2" class="deleteMenu ui-icon ui-icon-closethick">
               <span></span>
        </span>
        </span>
        <div id="menuEdit2" class="menuEdit hidden">
          <p>
            Content or form, or nothing here. Whatever you want.
          </p>
        </div>
      </div>
      <ol>
        <li style="display: list-item;" class="mjs-nestedSortable-branch mjs-nestedSortable-expanded" id="menuItem_4">
          <div class="menuDiv">
            <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
                   <span></span>
            </span>
            <span title="Click to show/hide item editor" data-id="4" class="expandEditor ui-icon ui-icon-triangle-1-n">
                   <span></span>
            </span>
            <span>
                   <span data-id="4" class="itemTitle">c</span>
            <span title="Click to delete item." data-id="4" class="deleteMenu ui-icon ui-icon-closethick">
                   <span></span>
            </span>
            </span>
            <div id="menuEdit4" class="menuEdit hidden">
              <p>
                Content or form, or nothing here. Whatever you want.
              </p>
            </div>
          </div>
          <ol>
            <li class="mjs-nestedSortable-leaf" id="menuItem_6">
              <div class="menuDiv">
                <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
                       <span></span>
                </span>
                <span title="Click to show/hide item editor" data-id="6" class="expandEditor ui-icon ui-icon-triangle-1-n">
                       <span></span>
                </span>
                <span>
                       <span data-id="6" class="itemTitle">e</span>
                <span title="Click to delete item." data-id="6" class="deleteMenu ui-icon ui-icon-closethick">
                       <span></span>
                </span>
                </span>
                <div id="menuEdit6" class="menuEdit hidden">
                  <p>
                    Content or form, or nothing here. Whatever you want.
                  </p>
                </div>
              </div>
            </li>
          </ol>
        </li>
        <li style="display: list-item;" class="mjs-nestedSortable-leaf" id="menuItem_5">
          <div class="menuDiv">
            <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
                   <span></span>
            </span>
            <span title="Click to show/hide item editor" data-id="5" class="expandEditor ui-icon ui-icon-triangle-1-n">
                   <span></span>
            </span>
            <span>
                   <span data-id="5" class="itemTitle">d</span>
            <span title="Click to delete item." data-id="5" class="deleteMenu ui-icon ui-icon-closethick">
                   <span></span>
            </span>
            </span>
            <div id="menuEdit5" class="menuEdit hidden">
              <p>
                Content or form, or nothing here. Whatever you want.
              </p>
            </div>
          </div>
        </li>
      </ol>
    </li>
    <ol>
    </ol>
    <li style="display: list-item;" class="mjs-nestedSortable-leaf" id="menuItem_7">
      <div class="menuDiv">
        <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
               <span></span>
        </span>
        <span title="Click to show/hide item editor" data-id="7" class="expandEditor ui-icon ui-icon-triangle-1-n">
               <span></span>
        </span>
        <span>
               <span data-id="7" class="itemTitle">f</span>
        <span title="Click to delete item." data-id="7" class="deleteMenu ui-icon ui-icon-closethick">
               <span></span>
        </span>
        </span>
        <div id="menuEdit7" class="menuEdit hidden">
          <p>
            Content or form, or nothing here. Whatever you want.
          </p>
        </div>
      </div>
    </li>
    <li class="mjs-nestedSortable-leaf" id="menuItem_3">
      <div class="menuDiv">
        <span title="Click to show/hide children" class="disclose ui-icon ui-icon-minusthick">
               <span></span>
        </span>
        <span title="Click to show/hide item editor" data-id="3" class="expandEditor ui-icon ui-icon-triangle-1-n">
               <span></span>
        </span>
        <span>
               <span data-id="3" class="itemTitle">b</span>
        <span title="Click to delete item." data-id="3" class="deleteMenu ui-icon ui-icon-closethick">
               <span></span>
        </span>
        </span>
        <div id="menuEdit3" class="menuEdit hidden">
          <p>
            Content or form, or nothing here. Whatever you want.
          </p>
        </div>
      </div>
    </li>
  </ol>

  <ol class="moved ui-sortable mjs-nestedSortable-branch mjs-nestedSortable-expanded" style="border: 1px red solid; min-height:100px;">

  </ol>




  <h3>Try the custom methods:</h3>

  <p>
    <br>
    <input id="serialize" name="serialize" type="submit" value="Serialize">
  </p>
  <pre id="serializeOutput">
        </pre>

  <p>
    <input id="toArray" name="toArray" type="submit" value="To array">
  </p>
  <pre id="toArrayOutput">
        </pre>

  <p>
    <input id="toHierarchy" name="toHierarchy" type="submit" value="To hierarchy">
  </p>
  <pre id="toHierarchyOutput">
        </pre>

  <p><em>Note: This demo has the <code>maxLevels</code> option set to '4'.</em>
  </p>
</section>
<!-- END #demo -->

<section id="license">
  <h4>License</h4>

  <p>This work is licensed under the MIT License.
    <br>Which means you can do pretty much whatever you want with it.</p>

  <p>&copy; 2010&dash;2014 Manuele J Sarfatti</p>
</section>
<!-- END #documentation -->

If you want to see Fiddle

Shirish Patel
  • 874
  • 6
  • 14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/67708/discussion-between-alexander-and-anders-svensson). – Shirish Patel Dec 26 '14 at 10:38
  • @AndersSvensson 1) mjs-nestedSortable-leaf This class is not available on some DOM so we are not able to select those DOMS. 2) To select each item you need to add `$('li').on('click', function(e) {e.stopPropagation();$(this).toggleClass('selected');});` – Shirish Patel Dec 26 '14 at 11:09
  • @AndersSvensson After selecting different level DOM you can not drop out of box (It's some thing like you are selecting items from different folder and drop in other folder). it's not possible with nestedSortable event not in jqueryUI. – Shirish Patel Dec 26 '14 at 11:20
  • 2
    @AndersSvensson you need to use drag and drop – Shirish Patel Dec 26 '14 at 11:30
  • Sorry, wasn't able to join a chat today, but thanks. This is working fairly well now. I can live with the fact that I can't select from different levels at once. There seems to be that one bug remaining (sometimes an item gets hidden, for no apparent reason, when you click it. Any idea why? And please explain what your last comment meant "you need to use drag and drop", that's what I am doing, and what the whole problem is about, right? Do I misunderstand you? I'll accept your answer now, but I'd be really grateful if you could shed some light on these questions... – Anders Dec 26 '14 at 15:35
  • 1
    No as per my knowledge currently you are using nested sortable not drag and drop ... – Shirish Patel Dec 26 '14 at 15:47
  • And for the hidden properties issue... it's might be due to the css class .selected.hidden – Shirish Patel Dec 26 '14 at 15:49
  • Right, I'm using nestedSortable, but of course it includes drag and drop functionality...? So what would I need from the Draggable interaction in jQuery UI, which is what I suppose you mean? Would it add anything over and above the dragging functionality nestedSortable already has? Regarding the .selected.hidden I already knew that, just not why it happens unexpectedly, but I'll figure that out! Thanks – Anders Dec 27 '14 at 13:22
  • If you are using any sortable then you can select same level DOM and drop it. – Shirish Patel Dec 27 '14 at 17:44
  • And drag and drop means you can drag and drop any DOM any level with in drop scope. Even you can select more then one DOM of different level in single time and drag and drop it – Shirish Patel Dec 27 '14 at 17:51
  • Ok, using jQuery UI Draggable then? Not sure how to do that, do you know any example of it? I consider this question answered and has marked it so, but it would be interesting to know how multilevel drag and drop could be accomplished using draggable as you suggest. Tried moving this to chat, but not sure how that works. The latest comments didn't seem to come along... – Anders Dec 27 '14 at 18:48
1

I don't think you can select multiple draggable elements with the out-of-box jQuery UI sortable feature.

An alternate solution would be to select the draggable item when an item is triggered(rightclick, mouseover, click). Once the multi selection has been made, then drag them to their target.

Here's a link to your updated fiddle implementing what I described above, along with a snippet of your code.

$('.droptrue').on('click', 'li', function () {
    $(this).toggleClass('selected');
})
.on('contextmenu', 'li', function()
{
    $(this).toggleClass('selected');
    return false;
});
Kevin
  • 2,752
  • 1
  • 24
  • 46
  • Sorry, I don't understand what this would add? The fiddle I linked to (not mine btw, as I mentioned I found it in the other SO question) already managed to multi-select and drag and drop. However, what I need is to achieve the same thing with the nestedSortable plugin. I may have been unclear about what exactly that plugin is, I'll add a link. – Anders Dec 20 '14 at 13:57