Jump to content

Multiple Draggable Elements ?


vmars316

Recommended Posts

Hello & Thanks ,

I would like to take w3schools code:

https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_draggable 

And replace the 

  <p>Move</p>
  <p>this</p>
  <p>DIV</p>

with multiple "textareas" :

<textarea class="textArea" rows="4" cols="20"> </textarea>

As I do here: 

https://www.w3schools.com/code/tryit.asp?filename=G6WWH7C8BR89

(Please note the behavior of <trextarea> , how you can Drag the textarea

from the right bottom corner

and resize the whole 'mydiv' . )

 

And then then I want to add multiple "mydiv" structures:

<div id="mydiv">
  <div id="mydivheader">Click here to move</div>
<textarea class="textArea" rows="4" cols="20"> </textarea>
</div>

So that I can drag them around .

Please show me how to modify the code to make it do this .

Thank you very much !

Also , 

dragElement(document.getElementById("mydiv"));

what exactly is being put into dragElement ?

A reference to "mydiv" or "mydivheader"  ? 

How does dragElement know to only Drag "mydivheader" 

and not <textarea> . 

_______________________

I like this code very much , but it doesn't work with the < textarea> structure .

https://www.w3schools.com/code/tryit.asp?filename=G6WXCFPNLL4E

Edited by vmars316
Link to comment
Share on other sites

vmars, did this solution not work out for you?

On 8/2/2019 at 9:44 AM, Funce said:

Hey there vmars, your issue here is that getElementByID only ever gets one element. getElementsByClassName gets a collection of elements, so some things needs to be adjusted.

You'll need to apply the DragElement function to all of the Elements in the collection. (For loop might work well)
Your headers will no longer work as they use the passed element's id. You'll need to apply a "header" custom class, one that will exist on all the headers. You can then access this header element for dragging purposes by using the below code.


function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (elmnt.getElementsByClassName("header")[0]) {
    /* if present, the header is where you move the DIV from:*/
    elmnt.getElementsByClassName("header")[0].onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }

Try this and then go from there.

The code above should work with this type of HTML provided you've applied dragElement to each one of these that you require.

<div class="mydiv">
  <div class="header">Click here to move</div>
  <textarea class="textArea" rows="4" cols="20"> </textarea>
</div>
On 8/12/2019 at 7:21 PM, vmars316 said:

Also , 


dragElement(document.getElementById("mydiv"));

what exactly is being put into dragElement ?

A reference to "mydiv" or "mydivheader"  ? 

How does dragElement know to only Drag "mydivheader" 

and not <textarea> . 

dragElement specifically takes a "mydiv" Element. dragElement only applies the "draggable" behaviour to the header. The reason why the function takes the mydiv Element instead of the header, is that sometimes the header doesn't exist and in that case the "draggable" behaviour is applied to mydiv.

 

In regards to that other code, the textarea probably prevents propagation of click events in its center area, so it cannot be dragged unless you're right on the edge.

Link to comment
Share on other sites

Thanks Funce:

Is this what you mean ?

Code below .

<!DOCTYPE html>
<html>
<style>
.mydiv {
  position: absolute;
  z-index: 9;
  background-color: #f1f1f1;
  text-align: center;
  border: 1px solid #d3d3d3;
}

.mydivheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}
</style>
<body>

<h5>HelpMeDoThis-Multi-Draggable-ID-Element-w3Schools-FUNCE.html</h5>

<p>Click and hold the mouse button down while moving the DIV element</p>

<div class="mydiv">
  <div id="mydivheader">Click here to move</div>
<textarea class="textArea" rows="4" cols="20"> </textarea>
</div>

<div class="mydiv">
  <div id="mydivheader">Click here to move</div>
<textarea class="textArea" rows="4" cols="20"> </textarea>
</div>

<script>
//Make the DIV element draggagle:
dragElement(document.getElementByClassName("mydiv"));

function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (elmnt.getElementsByClassName("mydivheader")[0]) {
    /* if present, the header is where you move the DIV from:*/
    elmnt.getElementsByClassName("mydivheader")[0].onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }
  }
  
  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // set the element's new position:
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    /* stop moving when mouse button is released:*/
    document.onmouseup = null;
    document.onmousemove = null;
  }
}
</script>

</body>
</html>

'mydivheader' has lost its color 

and won't drag anymore . 

Thanks

Link to comment
Share on other sites

You haven't changed your headers from id= to class= in your HTML

Also, you'll need to loop through the collection provided by getElementsByClass by using a for loop, rather than directly putting it into dragElement

var mydivs = document.getElementsByClassName("mydiv");
for (var i = 0; i < mydivs.length; i++) {
  dragElement(mydivs[i]);
}

Disclaimer: Untested

Link to comment
Share on other sites

<!DOCTYPE html>
<html>
<style>
.mydiv {
  position: absolute;
  z-index: 9;
  background-color: #f1f1f1;
  text-align: center;
  border: 1px solid #d3d3d3;
}

.mydivheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}
</style>
<body>

<h1>Draggable DIV Element</h1>

<p>Click and hold the mouse button down while moving the DIV element</p>

<div class="mydiv">
  <div class="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>

<div class="mydiv">
  <div class="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>

<script>
//Make the DIV element draggagle:
dragElement(document.getElementByClassName("mydiv"));

function dragElement(elmnt) {

for (var elmnt = 0; elmnt < mydivs.length; elmnt++) {
  dragElement(mydiv[elmnt]);
}
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (document.getElementById(elmnt.class + "header")) {
    /* if present, the header is where you move the DIV from:*/
    document.getElementById(elmnt.class + "header").onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }

  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // set the element's new position:
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    /* stop moving when mouse button is released:*/
    document.onmouseup = null;
    document.onmousemove = null;
  }
}
</script>

</body>
</html>

Thanks Funce

I must have something in the wrong place 

'cause I am getting error: 

Uncaught TypeError: document.getElementByClassName is not a function

<!DOCTYPE html>
<html>
<style>
.mydiv {
  position: absolute;
  z-index: 9;
  background-color: #f1f1f1;
  text-align: center;
  border: 1px solid #d3d3d3;
}

.mydivheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}
</style>
<body>

<h1>Draggable DIV Element</h1>

<p>Click and hold the mouse button down while moving the DIV element</p>

<div class="mydiv">
  <div class="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>

<div class="mydiv">
  <div class="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>

<script>
//Make the DIV element draggagle:
dragElement(document.getElementByClassName("mydiv"));

function dragElement(elmnt) {

for (var elmnt = 0; elmnt < mydivs.length; elmnt++) {
  dragElement(mydiv[elmnt]);
}
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (document.getElementById(elmnt.class + "header")) {
    /* if present, the header is where you move the DIV from:*/
    document.getElementById(elmnt.class + "header").onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }

  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // set the element's new position:
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    /* stop moving when mouse button is released:*/
    document.onmouseup = null;
    document.onmousemove = null;
  }
}
</script>

</body>
</html>

Thanks

Link to comment
Share on other sites

On 8/15/2019 at 9:00 PM, Funce said:

You haven't changed your headers from id= to class= in your HTML

Also, you'll need to loop through the collection provided by getElementsByClass by using a for loop, rather than directly putting it into dragElement


var mydivs = document.getElementsByClassName("mydiv");
for (var i = 0; i < mydivs.length; i++) {
  dragElement(mydivs[i]);
}

Disclaimer: Untested

Thanks Funce 

Sorry , I am confused where things should go: 

	<!DOCTYPE html>
<html>
<style>
.mydiv {
  position: absolute;
  z-index: 9;
  background-color: #f1f1f1;
  text-align: center;
  border: 1px solid #d3d3d3;
}
	.mydivheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}
</style>
<body>
	<h1>Draggable DIV Element</h1>
	<p>Click and hold the mouse button down while moving the DIV element</p>
	<div class="mydiv">
  <div class="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>
	<div class="mydiv">
  <div class="mydivheader">Click here to move</div>
  <p>Move</p>
  <p>this</p>
  <p>DIV</p>
</div>
	<script>
//Make the DIV element draggagle:
var elmnt = 0; 
var mydiv;
//  dragElement(mydiv[elmnt]);
	function dragElement(elmnt) {
	
  dragElement(mydiv[elmnt]);
	//for (var elmnt = elmnt; elmnt < mydivs.length; elmnt++) {
//  dragElement(mydiv[elmnt]);
// }
	
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (document.getElementById(elmnt.ClassName + "header")) {
    /* if present, the header is where you move the DIV from:*/
    document.getElementById(elmnt.class + "header").onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }
	  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // get the mouse cursor position at startup:
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // call a function whenever the cursor moves:
    document.onmousemove = elementDrag;
  }
	  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // calculate the new cursor position:
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // set the element's new position:
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  }
	  function closeDragElement() {
    /* stop moving when mouse button is released:*/
    document.onmouseup = null;
    document.onmousemove = null;
  }
}
</script>
	</body>
</html>
	

 

 

 

Edited by vmars316
Link to comment
Share on other sites

23 hours ago, dsonesuk said:

document.getElementById() = singular

document.getElementsByClassName() = multiple.

I think I understand what you are saying :

"document.getElementsByClassName()" returns a nodeList . "

So I need to parse that list ,  but for 

"document.getElementsByClassName()" returns a nodeList . " 

(

I get error: 

" Uncaught TypeError: elmnt.getElementsByClassName is not a function " .

)

Once I solve that , then I can proceed with this following question

about " function dragElement(elmnt) " 

(

So if " elmnt " is that nodeList ,

What does it look like ?

Does it show two "mydiv" ? 

If so then how do I determine which "mydiv" was clicked ? 

)

	//Make the DIV element draggagle:
dragElement(document.getElementsByClassName("mydiv"));
	function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  if (elmnt.getElementsByClassName("mydivheader")[0]) {
    /* if present, the header is where you move the DIV from:*/
    elmnt.getElementsByClassName("mydivheader")[mydiv].onmousedown = dragMouseDown;
  } else {
    /* otherwise, move the DIV from anywhere inside the DIV:*/
    elmnt.onmousedown = dragMouseDown;
  }
  }
	

Thanks for sticking with me !

Link to comment
Share on other sites

3 hours ago, vmars316 said:

I think I understand what you are saying :

"document.getElementsByClassName()" returns a nodeList . "

This was made bold to emphasize that you spelled it wrong (as Element instead) and to indicate plurality.

3 hours ago, vmars316 said:

I get error: 

" Uncaught TypeError: elmnt.getElementsByClassName is not a function " .

 

Once I solve that , then I can proceed with this following question

So if " elmnt " is that nodeList ,

What does it look like ?

Does it show two "mydiv" ? 

If so then how do I determine which "mydiv" was clicked ? 

 

Thanks for sticking with me !

dragElement is only supposed to take an element, therefore elmnt is an Element. Passing in a NodeList will give you that TypeError, as a NodeList does not have that function.

If you include my for loop, as written in my previous, in your code, we can see what the error is going forward from there.

Link to comment
Share on other sites

Here's what have so far 
BUT I am still getting an error:
" Uncaught TypeError: Cannot set property 'onmousedown' of undefined "
Pls, what am I doing wrong 

//Make the DIV element draggagle:
//dragElement(document.getElementsByClassName("mydiv"));
	dragElement(document.querySelectorAll("p")); 
	var elmnt ;   var i;
function dragElement(elmnt) {
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  for (i = 0; i < elmnt.length; i++) { 
    if  (this.elmnt) { break; }
      }
  elmnt[i] = document.getElementsByClassName("mydivheader"); {
    /* if present, the header is where you move the DIV from:*/
    elmnt[i].onmousedown = dragMouseDown; // ERROR HERE
  } 
//  else {
//    /* otherwise, move the DIV from anywhere inside the DIV:*/
//    elmnt[i].onmousedown = dragMouseDown;
//  }
  }
	


Yes , dsonesuk and Funce :
I will do everything you say :
But AGAIN I ASK :
What is the purpose of these two statements :

dragElement(document.getElementsByClassName("mydiv"));
dragElement(document.querySelectorAll("p")); 

AND what is that purpose called (It must have a name (Then I can study up on it .))?
AND what are these statements doing ?
HOW do they relate to  " function dragElement(elmnt) {} " 

 

AND why is this method ok :

dragElement(document.getElementById("mydiv")); "

but this is not ,  and how could I code it so it is useable ? :

" dragElement(document.getElementsByClassName("mydiv")); "

Thanks

Edited by vmars316
Link to comment
Share on other sites

3 minutes ago, vmars316 said:

Here's what have so far 
BUT I am still getting an error:
" Uncaught TypeError: Cannot set property 'onmousedown' of undefined "
Pls, what am I doing wrong 

You've made a lot of unnecessary changes to the dragElement function. The whole function was never designed in such a way that it would take a collection. If you take my first post with the DragElement function, then before it include the for loop I provided, you won't have too many problems.

4 minutes ago, vmars316 said:

What is the purpose of these two statements :

dragElement(document.getElementsByClassName("mydiv"));
dragElement(document.querySelectorAll("p")); 

AND what is that purpose called (It must have a name (Then I can study up on it .))?
AND what are these statements doing ?
HOW do they relate to  " function dragElement(elmnt) {} "

If you're unsure about the use of functions, invocations and how they apply, have a look here: https://www.w3schools.com/js/js_function_definition.asp

If you're specifically looking at our example, I'll provide a small explanation.

The purpose of dragElement is to bind some onclick events to the provided element. Depending on if it has a header or not, depends on whether the header gets the behaviour or the whole element.

dragElement(document.getElementById("mydiv")) in this case here, elmnt would be the Element returned by getElementById.

 

In our example, we're trying to do multiple at the same time, so we first get a list of the elements that have the mydiv class. Then we need to bind each and every one of them with on click handlers. Binding the collection does nothing, as its not an Element and lacks the properties for binding. So a for loop is used as shown in my previous post.
This means you may treat elmnt, as any one of your given mydiv Elements. Not all of them at once. Only one.

Link to comment
Share on other sites

17 minutes ago, dsonesuk said:

You are passing the identity of the specific elements to process along with the function called to do the processing. The for loop curly braces start and finish  after the first if conditioning and any code with [ i ] should be within those braces.

Plz , what question are you responding to ?

Thanks

Link to comment
Share on other sites

OK  Funce 

I have poor eysite , and a learning disability ,

so let me absorb this , it may take a while . 

I have to see example first and work backwards , 

I realize it makes more work for you folks , and I apologize for that .

so yes , an explanation would tremendously useful :

https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_draggable 

Thanks

 

 

Edited by vmars316
Link to comment
Share on other sites

1 hour ago, vmars316 said:

OK  Funce 

I have poor eysite , and a learning disability ,

so let me absorb this , it may take a while . 

I have to see example first and work backwards , 

I realize it makes more work for you folks , and I apologize for that .

Apologies vmars, I didn't intend to sound condescending or aggravated. If that is what you heard then allow me to apologize again.

I'll keep this one short.

  • Take my For Loop
  • Take the Original Drag Element Code
  • Replace dragElement code with my Replacement dragElement code (changing "header" to "mydivheader")

Result: https://www.w3schools.com/code/tryit.asp?filename=G75VCGLH4SCA

Link to comment
Share on other sites

  • 6 months later...

Hey @vmars316,

you can create a draggable element in easy way using jQuery plugins. Following is the example code which you can refer:

 

 
 
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Draggable - Default functionality</title>
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <style>
  </style>
  <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>
  <script>
  $( function() {
    $( "#draggable" ).draggable();
  } );
  </script>
</head>
<body>
 
<div id="draggable" class="ui-widget-content">
    <p>Move</p>
    <p>this</p>
    <p>DIV</p>
    <textarea class="textArea" rows="4" cols="20"> </textarea>
    <div id="mydiv">
        <div id="mydivheader">Click here to move</div>
      <textarea class="textArea" rows="4" cols="20"> </textarea>
      </div>
</div>
 
 

Here 

 <link rel="stylesheet" href="https://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>

These are the CDN to import plugins to our code.

you can also apply that draggable() function to multiple divs.

Edited by ishan_shah
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...