0
votes

I have a nested list items and would like to achieve drag and drop functionality.

Scenario:

  1. one level tree structure
  2. child items directly on root node and in first level tree node
  3. move child items out of tree node or in to tree node
  4. restrict tree nodes to drag

HTML

<ul id="sortable1" class="connectedSortable">
  <li class="ui-state-default">Item 1</li>
  <li class="folder"> Empty Folder
    <ul id="sortable1" class="connectedSortable">

    </ul>
  </li>
  <li class="ui-state-default">Item 2</li>
  <li class="ui-state-default">Item 3</li>
  <li class="folder"> Folder 1
    <ul id="sortable2" class="connectedSortable">
  <li class="ui-state-default">Item 4</li>
  <li class="ui-state-default">Item 5</li>
  </ul>
  </li>
  <li class="ui-state-default">Item 7</li>
  <li class="ui-state-default">Item 8</li>
  <li class="folder"> Folder 2
    <ul id="sortable2" class="connectedSortable">
  <li class="ui-state-highlight">Item 1</li>
  <li class="ui-state-highlight">Item 2</li>
  <li class="ui-state-highlight">Item 3</li>
  <li class="ui-state-highlight">Item 4</li>
  <li class="ui-state-highlight">Item 5</li>
</ul>
  </li>
</ul>

JS/jQuery

$(function() {
    $( ".connectedSortable" ).sortable({
      connectWith: ".connectedSortable"
    }).disableSelection();
  });

Example at JS Fiddle

I would like to be able to move a item in to Empty folder as well, restrict folders to move, restrict sorting items, move only if item is moved out of the folder or in to a folder. And on successful move call a function, where I can read the item Id and folder Id and do some logic.

2
I'm confused. In your example you can move items into the empty folder. - Stryner
@Stryner if you see my markup, there is a "Empty folder" <li class="folder"> Empty Folder <ul id="sortable1" class="connectedSortable"> </ul> I should be able to move a item in to it. currently in my JS Fiddle it is not working. - HaBo
You mean like this? - Stryner
Yes, but folder should not be movable only items should be movable - HaBo

2 Answers

1
votes

for having drag-drop treeview , you better use nestedSortable, it's very easy. here is a sample of how you can use it

<ol class="sortable">
    <li id="list_1"><div><span class="disclose"><span></span></span>Item 1</div>
      <ol>
        <li id="list_2"><div><span class="disclose"><span></span></span>Sub Item 1.1</div>
          <ol>
            <li id="list_3"><div><span class="disclose"><span></span></span>Sub Item 1.2</div>
          </ol>
      </ol>
    <li id="list_4"><div><span class="disclose"><span></span></span>Item 2</div>
    <li id="list_5"><div><span class="disclose"><span></span></span>Item 3</div>
      <ol>
        <li id="list_6" class="mjs-nestedSortable-no-nesting"><div><span class="disclose"><span></span></span>Sub Item 3.1 (no nesting)</div>
        <li id="list_7"><div><span class="disclose"><span></span></span>Sub Item 3.2</div>
          <ol>
            <li id="list_8"><div><span class="disclose"><span></span></span>Sub Item 3.2.1</div>
          </ol>
      </ol>
    <li id="list_9"><div><span class="disclose"><span></span></span>Item 4</div>
    <li id="list_10"><div><span class="disclose"><span></span></span>Item 5</div>
  </ol>

and the javascripts

  $(document).ready(function(){
      $('ol.sortable').nestedSortable({
        forcePlaceholderSize: true,
        handle: 'div',
        helper: 'clone',
        items: 'li',
        opacity: .6,
        placeholder: 'placeholder',
        revert: 250,
        tabSize: 25,
        tolerance: 'pointer',
        toleranceElement: '> div',
        maxLevels: 3,

        isTree: true,
        expandOnHover: 700,
        startCollapsed: true,
        start: function(e, ui) {
          //some code
        },
        receive: function(e, ui) {
         //some code
        },
        stop: function(e, ui) {
            //code of Serialize
            //this happend when the move complete
            var treeSerialize = jQuery('ol.sortable').nestedSortable('updatecategories', {startDepthCount: 0});
            console.log(treeSerialize);
        }
      });
  });

demo, it's very nice and good, it use it on several app, for menu, categories, and other nested things

0
votes

This is how I ended up to complete it. Fiddle Demo

Javascript

$(function() {
   // $( "ul[id^='sortable']" ).sortable({
  //    connectWith: ".connectedSortable"
   // }).disableSelection();
   $( "li.product" ).draggable({
      appendTo: "body",
      helper: "clone"
    });
     $( ".folder" ).droppable({
      activeClass: "ui-state-default",
      hoverClass: "ui-state-hover",
      accept: ":not(.ui-sortable-helper)",
      drop: function( event, ui ) {
        //$( this ).find( ".placeholder" ).remove();
        //$( "<li></li>" ).text( ui.draggable.text() ).appendTo( this );
        alert("Dragging Product Id is "+$(ui.draggable).attr("id") + "Dropping Folder Id is "+ $(event.target).attr("id"));
      }
    })
  });

Mark up

<ul id="sortablex"><li class="folder"> 
<ul>
  <li  id="1" class="ui-state-default product">Product 1</li>
</ul>

  </li>
  <li id="1"  class="folder"> Empty category
    <ul id="sortable1" class="connectedSortable">

    </ul>
  </li>
  <li id="1" class="ui-state-default product">Product 2</li>
  <li  id="1" class="ui-state-default product">Product 3</li>
  <li id="f1"  class="folder"> Category 1
    <ul id="sortable2" class="connectedSortable">
  <li  id="1" class="ui-state-default product">Product 4</li>
  <li  id="1" class="ui-state-default product">Product 5</li>
  </ul>
  </li>
  <li  id="1" class="ui-state-default product">Product 7</li>
  <li  id="1" class="ui-state-default product">Product 8</li>
  <li id="1"  class="folder"> Category 2
    <ul id="sortable2" class="connectedSortable">
  <li  id="1" class="ui-state-highlight product">Product 1</li>
  <li  id="1" class="ui-state-highlight product">Product 2</li>
  <li  id="1" class="ui-state-highlight product">Product 3</li>
  <li  id="1" class="ui-state-highlight product">Product 4</li>
  <li  id="1" class="ui-state-highlight product">Product 5</li>
</ul>
  </li>
</ul>

CSS

folder{
   color:#c30;
   font-weight:bold;
  }
  .folder ul{
    color:#000;
    font-weight:normal;
  }