0

I used bootstrap css and JqueryUI to create a list in draggable <ul> and made a <div> as droppable area. Now the drag and drop both work properly.

    <ul id="showdata" class="list-group ui-helper-reset ui-droppable" style="overflow: auto; height: 200px; display: block;">
    <li class="list-group-item ui-draggable ui-draggable-handle">_Unassigned_<a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

    </li>
    <li class="list-group-item ui-draggable ui-draggable-handle">_Unassigned_<a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

    </li>
    <li class="list-group-item ui-draggable ui-draggable-handle">_Unassigned_<a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

    </li>
    <li class="list-group-item ui-draggable ui-draggable-handle">_Unassigned_<a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

    </li>
    <li class="list-group-item ui-draggable ui-draggable-handle">_Unassigned_<a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

    </li>
    <li class="list-group-item ui-draggable ui-draggable-handle">_Unassigned_<a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

    </li>
</ul>
<div class="col-md-6" id="dropdiv">
    <label for="Drag_Your_Selection_Here">Drag Your Selection Here</label>
    <div id="droppable" class="col-md-pull-12 ui-droppable" style="border: 2px solid gray; overflow: auto; height: 200px; display: block;"></div>
</div>

I'd like to have a click function:

1.When clicking "+", the list can be added in droppable <div>.

2.When clicking "x", the list can be added back to where it was.

var $showdata = $("#showdata"),
      $droppable = $("#droppable");
  // make draggable<ul>→<li> draggable//
  $("#showdata > li").draggable({
      cancel: "a.glyphicon.glyphicon-plus", // clicking an icon won't initiate dragging
      revert: "invalid", // when not dropped, the item will revert back to its initial position
      containment: "document",
      helper: "clone",
      cursor: "move"
  });

  //make droppable<div> droppable
  $droppable.droppable({
      accept: "#showdata > li",
      activeClass: "ui-state-highlight",
      hoverClass: "ui-state-hover",
      accept: ":not(.ui-sortable-helper)",
      drop: function (event, ui) {
          addlist(ui.draggable);
      }
  }).sortable({
      sort: function () {
          $(this).removeClass("ui-state-highlight");

      }
  }).disableSelection();

  // make DRAGGABLE<div> droppable, accepting items from droppable<div>
  $showdata.droppable({
      accept: "#droppable li",
      activeClass: "ui-state-highlight",
      drop: function (event, ui) {
          deletelist(ui.draggable);
      }
  });
  // init delete<a>
  var del_icon = "<a href='#del' id='del_id' class='glyphicon glyphicon-remove' title='delete group to selection' style='float: right'></a>";
        `
// find <li> to get back to where it was found
      function addlist($item) {
          $item.fadeOut(function () {
              var $list = $("ul", $droppable).length ? $("ul", $droppable) : $("<ul class='list-group ui-helper-reset'></ul>").appendTo($droppable);
              $item.find("a.glyphicon.glyphicon-plus").remove();
              $item.append(del_icon).appendTo($list).fadeIn();
          });
      };
      //init add<a>
      //var add_icon = "<a id='add_id' class='glyphicon glyphicon-plus' style='float: right'></a>";
      var add_icon = $("a.glyphicon.glyphicon-plus");

      //find <li> to delete
      function deletelist($item) {
          $item.fadeOut(function () {
              $item.find("a.glyphicon.glyphicon-remove").remove().end().append(add_icon).appendTo($showdata).fadeIn();
          });
      };
      // resolve the icons behavior with event delegation
      $($showdata > "li").click(function (event) {
          var $item = $(this),
              $target = $(event.target);

          if ($target.is("a.glyphicon.glyphicon-plus")) {
              deletelist($item);
          } else if ($target.is("a.glyphicon.glyphicon-remove")) {
              addlist($item);
          }
          return false;
      });`

drag and drop function

I also have the sortable function. But everytime I sort a list in droppable <div>, it adds one more <a> (which is the symbol "x") on that list.

Anyone can be able to solve these two problems? I'll sincerely appreciate that!

Here is my JsFiddle https://jsfiddle.net/woodmanhu/87cjr896/5/

T J
  • 42,762
  • 13
  • 83
  • 138
QIWEN HU
  • 239
  • 2
  • 8
  • 19

1 Answers1

0

From what I see, it's easier to achieve what you're trying to by using the connectWith option of two sortables.

Major problem with trying to achieve this with

(droppable container > draggable items ) + sortable

is that you won't have any space to drop an item back from the sortable into tightly packed draggable items. But when it comes to sortable, it'll automatically insert helpers to facilitate dropping.

So it is better to make $("#showdata") a sortable in which sorting is disabled, as shown below:

$("#showdata").sortable({
  revert: "invalid",
  helper: "clone",
  connectWith: "#droppable",
  receive: function(e, ui) {
    ui.item.fadeOut(function() {
      ui.item.appendTo(this).fadeIn().find("a.glyphicon.glyphicon-remove").removeClass('glyphicon-remove').addClass('glyphicon-plus');
    });
  },
  stop: function(e, ui) {
    if (ui.item.parent().attr('id') == 'showdata') {
      $('#showdata').sortable("cancel");
    }
  }
});
$("#droppable").sortable({
  accept: "#showdata > li",
  accept: ":not(.ui-sortable-helper)",
  connectWith: "#showdata",
  receive: function(e, ui) {
    var $this = this;
    ui.item.fadeOut(function() {
      $(this).appendTo($this).fadeIn().find("a.glyphicon").removeClass('glyphicon-plus').addClass('glyphicon-remove');
    });
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<ul id="showdata" class="list-group ui-helper-reset ui-droppable" style="overflow: auto; height: 200px; display: block;">
  <li class="list-group-item ui-draggable ui-draggable-handle">1
    <a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

  </li>
  <li class="list-group-item ui-draggable ui-draggable-handle">2
    <a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

  </li>
  <li class="list-group-item ui-draggable ui-draggable-handle">3
    <a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

  </li>
  <li class="list-group-item ui-draggable ui-draggable-handle">4
    <a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

  </li>
  <li class="list-group-item ui-draggable ui-draggable-handle">5
    <a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

  </li>
  <li class="list-group-item ui-draggable ui-draggable-handle">6
    <a href="#add" id="add_id" class="glyphicon glyphicon-plus" title="add group to selection" style="float: right"></a>

  </li>
</ul>
<div class="col-md-6" id="dropdiv">
  <label for="Drag_Your_Selection_Here">Drag Your Selection Here</label>
  <ul id="droppable" class="col-md-pull-12 ui-droppable" style="border: 2px solid gray; overflow: auto; height: 200px; display: block;"></ul>
</div>
T J
  • 42,762
  • 13
  • 83
  • 138
  • Thank you so much for your reply! I can sufficiently see that this one would work better when I apply to my project. Several questions I'd like to ask. 1. Do I still need to keep the '$("#showdata > li").draggable' function and '$droppable.droppable' function if I apply your sortable functions there? Or I just add them behind these functions? – QIWEN HU Oct 20 '15 at 15:20
  • 2. "#showdata" '
      ' actually is not necessary to have sorting function, but I understand it has to have that to enable the sort function so that it can open a space when I drag item back. But if I want the list back where exactly it was found, do I need to give a function that remembers what the sequence of list was? So when I drag back from `$droppable`, it can trigger the remember function?
    – QIWEN HU Oct 20 '15 at 15:26
  • @QIWENHU Hi, sortable widget contains both `draggable` and `droppable` functionality, plus more. Initializing it as `draggable` and `droppable` separately is not necessary, it'll only cause trouble. For remembering the previous position, you can use the `update` callback option, where you can rearrange the elements the way you want. `$showdata` is a jquery object. `object > string` is not a valid selector so your click doesn't work. you can do `$("li",$showdata)` instead. – T J Oct 21 '15 at 04:38
  • Thank you sou much for your help! – QIWEN HU Oct 21 '15 at 16:08