Mikhail Klinov
Mikhail Klinov

Reputation: 21

Why does draggable not work for dynamically created elements?

My draggable elements are created dynamically. every time I add an item, I call draggable() again. They get draggable classes, but don't drag.

When writing draggable to the debug console, it successfully works with non-dynamic elements.

$(window).on('load', function () {
    var item = '<div class="item"></div>';
    $field.append(item);
    dragItems();

});

function dragItems() {
    var $items = $('.item');

    $items.draggable();

}

In the inspector, I see that the drag classes are created, but the movement does not occur.

Upvotes: 1

Views: 484

Answers (1)

Twisty
Twisty

Reputation: 30883

Consider the following example.

$(function() {
  function dragItems(dObj) {
    dObj.draggable({
      containment: "parent"
    });
  }

  var item = '<div class="item"></div>';
  $("#field").append(item);
  dragItems($("#field .item"));
});
#field {
  width: 400px;
  height: 200px;
  background: #CFC;
}

.item {
  width: 100px;
  height: 100px;
  background: #CCC;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="field"></div>

I suspect there is more code to your example. This is wrapped in $(function(){}); which will wait until the document is ready. Similar to $(window).on('load').

The function is setup to accept a jQuery Object and assign Draggable to the Object. So you have to pass it the $("#field .item") object.

Now if you had created the object first, could be a little less code. Your current code is not creating an object but injecting HTML string by append. Consider the following.

$(function() {
  function dragItems() {
    $("#field .item").draggable({
      containment: "parent"
    });
  }

  var item = $("<div>", {
    class: "item"
  });
  $("#field").append(item);
  dragItems();
});
#field {
  width: 400px;
  height: 200px;
  background: #CFC;
}

.item {
  width: 100px;
  height: 100px;
  background: #CCC;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="field"></div>

This, I think, is more like what you want to do, where you just make all .item elements draggable. You can use either method. I would just make sure you create an Object one way or another to use with Dragable.

Hope that helps.

Upvotes: 2

Related Questions