grouping draggable objects with jquery-ui draggable

Jiaaro picture Jiaaro · Apr 27, 2009 · Viewed 33.5k times · Source

I want to use jquery draggable/droppable to let the user select a group of objects (each one has a checkbox in the corner) and then drag all the selected objects as a group...

I can't figure out for the life of me how to do it haha.

Here is what I'm thinking will lead to a usable solution, on each draggable object, use the start() event and somehow grab all the other selected objects and add them to the selection

I was also considering just making the dragged object look like a group of objects (they're images, so a pile of photos maybe) for performance reasons. I think using the draggable functionality might fall over if you drag several dozen objects at once, does that sound like a better idea?

Answer

brianpeiris picture brianpeiris · May 2, 2009

You could use the draggable's helper option to drag groups of items.

For example, if your draggables have checkboxes, you can return the selected items from the helper function like so:

$('#dragSource li').draggable({
  helper: function(){
    var selected = $('#dragSource input:checked').parents('li');
    if (selected.length === 0) {
      selected = $(this);
    }
    var container = $('<div/>').attr('id', 'draggingContainer');
    container.append(selected.clone());
    return container; 
  }
}); 

Demo

I've setup a demo with draggable images with checkboxes and somewhat fluid layout. Click "Run Code Snippet" at the bottom to see the result:

$(function() {

  $('#dragSource li').draggable({
    helper: function() {
      var selected = $('#dragSource input:checked').parents('li');
      if (selected.length === 0) {
        selected = $(this);
      }
      var container = $('<div/>').attr('id', 'draggingContainer');
      container.append(selected.clone());
      return container;
    }
  });

  $('#dropTarget').droppable({
    tolerance: 'pointer',
    drop: function(event, ui) {
      $(this).append(ui.helper.children());
    }
  });

  $('#selectAll').click(function() {
    $('#dragSource input').prop('checked', true);
    return false;
  });

  $('#selectNone').click(function() {
    $('#dragSource input').prop('checked', false);
    return false;
  });

  $('#selectInvert').click(function() {
    $('#dragSource input').each(function() {
      var $this = $(this);
      if ($this.prop('checked')) {
        $this.prop('checked', false);
      } else {
        $this.prop('checked', true);
      }
    });
    return false;
  });
});
body {
  font-family: sans-serif;
  overflow-x: hidden;
}
div {
  margin: 5px;
  padding: 0;
}
ul {
  margin: 0;
  padding: 0;
}
li {
  list-style: none;
  padding: 0;
  margin: 0;
  float: left;
  white-space: nowrap;
}
#selectActions span,
#selectActions li {
  float: left;
  padding: 5px;
}
.droppableContainer {
  width: 48%;
  float: left;
  min-height: 200px
}
.droppableContainer li {
  height: 90px;
  width: 110px;
  margin: 2px;
  background-color: white;
  padding-bottom: 4px;
}
.droppableContainer img {
  width: 90px;
  max-height: 90px;
  max-width: 90px;
  width: 90px;
  vertical-align: middle;
}
.droppableContainer input {
  height: 90px;
  vertical-align: middle;
}
#draggingContainer {
  width: 48%;
}
#draggingContainer input {
  visibility: hidden;
}
#dropTarget {
  border: 3px dashed grey;
}
#dropTarget input {
  visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

<div id="selectActions">
  <span>Select:</span>
  <ul>
    <li><a id="selectAll" href="#">all</a>
    </li>
    <li><a id="selectNone" href="#">none</a>
    </li>
    <li><a id="selectInvert" href="#">invert</a>
    </li>
  </ul>
</div>
<div style="clear:left;">
  <div id="dragSource" class="droppableContainer">
    <ul>
      <li>
        <img src="http://imgs.xkcd.com/comics/drapes.png" /><input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/misusing_slang.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/donner.jpg" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/a_new_captcha_approach.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/bug.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/open_source.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/tag_combination.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/a_simple_plan.jpg" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/it_might_be_cool.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/hedgeclipper.jpg" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/pep_talk.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/regular_expressions.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/pwned.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/post_office_showdown.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/im_an_idiot.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/pointers.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/chess_photo.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/50_ways.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/e_to_the_pi_times_i.png" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/self-reference.jpg" />
        <input type="checkbox" />
      </li>
      <li>
        <img src="http://imgs.xkcd.com/comics/starwatching.png" />
        <input type="checkbox" />
      </li>
    </ul>
  </div>

  <div id="dropTarget" class="droppableContainer">
  </div>
</div>