-1

I'm trying to make divs created with .createElement be draggable. It works fine with divs that are already created like below:

 <div>
  This can be dragged around, but outputs cannot?!
</div>

but when I create new divs with the function addElement(), it doesn't work.

In more detail here is what my code aims to do: user inputs text -> clicks input button and the user input(s) are outputted on the screen and can be dragged.

Full code:

function addElement () { 
  var text = document.getElementById("input").value;
  // create a new div element 
  var newDiv = document.createElement("div");  

  // and give it some content 
  var newContent = document.createTextNode(text); 
  
  // add the text node to the newly created div
  newDiv.appendChild(newContent);  

  // add the newly created element and its content into the DOM 
  var currentDiv = document.getElementById("div1"); 
  document.body.insertBefore(newDiv, currentDiv); 

    document.getElementById("input").value = " ";

}

   $( function() {
  var div = document.getElementsByTagName('div');
    $( div ).draggable();
  } );
 div { width: 150px; height: 150px; padding: 0.5em; }
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
      <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <link rel="stylesheet" href="/resources/demos/style.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>
  </head>
  <body>
    <input id="input"type="text" placeholder=" text">
    <button onclick="addElement()" >Input</button>   
  
    <p>Outputs:</p>
     <script src="script.js"></script>
  </body>

</html>
 
<div>
  This can be dragged around, but outputs cannot?!
</div>
 
 
</body>
</html>
ap2634
  • 1
  • 1

4 Answers4

1

When you load the page, the draggable gets attached to the div element which is already loaded. But when you dynamically create a new element, the draggable is not re-attached to the new div. So, whenever you add a new div, you need to re-attach the draggable event to it:

function addElement() {
  var text = document.getElementById("input").value;
  // create a new div element 
  var newDiv = document.createElement("div");

  // and give it some content 
  var newContent = document.createTextNode(text);

  // add the text node to the newly created div
  newDiv.appendChild(newContent);

  // add the newly created element and its content into the DOM 
  var currentDiv = document.getElementById("div1");
  document.body.insertBefore(newDiv, currentDiv);

  $(function() {
    var div = document.getElementsByTagName('div');
    $(div).draggable();
  });

  document.getElementById("input").value = " ";

}

$(function() {
  var div = document.getElementsByTagName('div');
  $(div).draggable();
});
div {
  width: 150px;
  height: 150px;
  padding: 0.5em;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>repl.it</title>
  <link href="style.css" rel="stylesheet" type="text/css" />
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <link rel="stylesheet" href="/resources/demos/style.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>
</head>

<body>
  <input id="input" type="text" placeholder=" text">
  <button onclick="addElement()">Input</button>

  <p>Outputs:</p>
  <script src="script.js"></script>
</body>

</html>

<div>
  This can be dragged around, but outputs cannot?!
</div>


</body>

</html>
benhatsor
  • 1,863
  • 6
  • 20
0

When you load the page, the draggable gets attached to the div element which is already loaded. But when you dynamically create a new element, the draggable is not attached to the new div. Whenever you add a new div, you need to re-attach draggable event to it.

0

You only run

$( function() {
  var div = document.getElementsByTagName('div');
  $( div ).draggable();
} );

when your app loads for the first time, therefore newly created divs are not draggable.

When you want the new divs to be draggable, you have to add $( newDiv ).draggable() to your addElement() function.

Josef Wittmann
  • 1,259
  • 9
  • 16
0

You are using $(callback), which only calls the function once when the DOM is loaded.
However, when you add new elements, they will not be made draggable since the function that does it has already run.

To make the new elements draggable too, you will need to call jQuery.draggable() on them as well after creating them.
This means, you should add newDiv.draggable() inside your function that creates the elements.

Sidenote

When using an API like jQuery, you should try to stick to it rather than the native methods to make understanding it easier, since one wouldn't have to go back and forth in their mindsets.

Subnotes

  • You have incorrect HTML since you have a <div> after closing both <body> and <html>, and are trying to close them again at the end. Since HTML disallows elements outside of <body>, most browsers automatically correct this mistake. However, you should format the HTML correctly yourself.
  • Creating jQuery-elements using $(document.createElement('div')) instead of using $('<div>') is (minimally) faster, hence I use it below
  • Do not add the onclick-listener in the HTML, instead, add it using JavaScript. Adding the listener inline would require the function to be exposed in the global scope, and would pollute the global namespace. Listeners do not require to be named, and can easily be added in JS, allowing to not expose the functions to the global scope.

Making your code use mostly jQuery would make it look like this:

$(function() { // Executed once DOM loaded
  // Make all pre-existing 'div's draggable
  $('div').draggable();
  
  // Add the 'onclick'-listener using jQuery
  $('button').click(function() {
    // Creating jQuery-element this way; read about the reason in the sub-notes
    var newDiv = $(document.createElement("div"));
    newDiv.text($('#input').val()); // Set the text to the value of 'input'
    newDiv.draggable(); // Make it draggable

    $('body').append(newDiv); // Append it to the body

    $('#input').val(''); // Set 'input's value to ""
  });
});
div {
  width: 150px;
  height: 150px;
  padding: 0.5em;
}
<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  </head>
  <body>
    <input id="input" type="text" placeholder="text">
    <button>Input</button>

    <p>Outputs:</p>
    <div>
      This can be dragged around, but outputs cannot?!
    </div>
  </body>
</html>
Oskar Grosser
  • 2,804
  • 1
  • 7
  • 18