draggable does not apply to element created using append

1

What can I correct so that the .draggable() method is applied correctly to the elements created using the add button?

$(document).ready(function() {
  
  $('.drag_drop').draggable({
    addClasses: false,
    containment: "parent"
  });
  
  $('#add').click(function(){
    $('.parent').append('<div class="drag_drop">Aquí <b>no</b> funciona</div>')
  });
  
});
.parent {
  width: auto;
  height: 100px;
  border: 1px black solid;
}

.drag_drop {
  font-family: Arial;
  text-align: center;
  width: 80px;
  height: 80px;
  border: 1px black solid;
  float: left;
  margin: 5px 5px 5px 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div class="parent">
  <div class="drag_drop">
    Aquí funciona
  </div>
</div>
<br />
<button id="add" type="button">Añadir</button>
    
asked by Jorius 22.03.2017 в 18:27
source

2 answers

2

This happens because the drag feature is set to run only once when the document is ready. Therefore, when you add a new node to the document, it will not be applied to the new element.

For this, you would have to apply a "live" check for the new elements implemented in the document and then apply them .draggable() , what you could do with a .on("DOMNodeInserted ", function () but we will not go that way because that It's a bumpy and sensitive road for every project.

For this exact example in your question we can wrap the .draggable() in a function, and we call it when there is a click on the button.

$(document).ready(function() {
    function dragTrack() {
        $('.drag_drop').draggable({
            addClasses: false,
            containment: "parent"
        });
    }
    dragTrack();

    $('#add').click(function(){
        $('.parent').append('<div class="drag_drop">Aquí <b>no</b> funciona</div>');
        dragTrack();
    });

});
.parent {
  width: auto;
  height: 100px;
  border: 1px black solid;
}

.drag_drop {
  font-family: Arial;
  text-align: center;
  width: 80px;
  height: 80px;
  border: 1px black solid;
  float: left;
  margin: 5px 5px 5px 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div class="parent">
  <div class="drag_drop">
    Aquí funciona
  </div>
</div>
<br />
<button id="add" type="button">Añadir</button>
    
answered by 22.03.2017 / 18:57
source
0

When the navigator interprets the whole page for the first time, a DOM tree is created of all the elements that are in that moment (that is why your first element if it works since it was created from the page).

Now JQuery creates a virtual DOM of the page and it does not change unless you refresh, so even if you see that the tables appear they do not exist in the DOM and therefore you can not apply the class you put.

What can be done? the short answer is called 'Propagation of events' and consists in telling the father of these elements that also exists from the beginning, that each time a child is added to him, he should say that he must belong to that class.

In your example it would be something like this:

$(document).ready(function() {
  
  
  
  $('#add').on("click",function(){
    $('#parent').append('<div>Aqui</div>');
    $('#parent').children().addClass("drag_drop");
    $('.drag_drop').draggable({
    addClasses: true,
    containment: "parent"
  });
   });
  
});
.parent {
  width: auto;
  height: 100px;
  border: 1px black solid;
}

.drag_drop {
  font-family: Arial;
  text-align: center;
  width: 80px;
  height: 80px;
  border: 1px black solid;
  float: left;
  margin: 5px 5px 5px 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div id="parent">
  <div class="drag_drop">
    Aquí funciona
  </div>
</div>
<br />
<button id="add" type="button">Añadir</button>
    
answered by 22.03.2017 в 19:20