Dragable element gets stuck after inserting second one - javascript

Hello I want to learn a bit more about javascript because i'm very new to javascript coding. I'm trying to create a small script that when you press a button a new Dom structure is created and it creates a small structure.
so far so good. After this my idea was to let those newly created structures be drageable.
I found some code from w3schools.com to create a dragable div.
now I'm running into a problem. when i create 1 new div structure I can drag this structure all around. after I create a 2nd one my entire javascript code seems to crash because I cannot move both the structures around my screen.
I think it got something to do with the creating of the div and that I name it 'mydiv'.
but this is just a guess (like I said i'm very new to Javascript coding)
DIV create code
function createDiv() {
let dom = '<div id="mydiv"><div id="mydivheader" class = "Filter"><button>test 1</button></div></div>';
let template = document.createElement("template");
template.innerHTML = dom;
document.body.innerHTML += template.innerHTML;
}
Dragable code
dragElement(document.getElementById("mydiv"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
/* if present, the header is where you move the DIV from:*/
document.getElementById(elmnt.id + "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;
}
}
HTML code Note: I added some jqueary scripts and other things like boodstrap in the hopes of getting it to work
<!DOCTYPE html>
<html lang="en">
<head>
<title>create dragable DOMS</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
</head>
<body>
<div>
<button onClick="createDiv()"> create </button>
</div>
<div>
</div>
</body>
<script> see code block </script>

Hey you forgot to add the css for us to see your draggable element !
First of all :
document.body.innerHTML += template.innerHTML;
Break all listeners when you execute that code , innerHTML parse the html code into string before adding a content and parses again to HTML Objects... losing all events associated in the page ..
So we gonna use :
document.body.appendChild()
Also , the element template doesnt works well for this ! Turns what is inside into document fragment . I'll use div in this example .
let myDiv = document.createElement("div")
Also made an 'counter' for you manage better all this .
See in action :
<!DOCTYPE html>
<html lang="en">
<head>
<title>create dragable DOMS</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<style>
#myDiv {
position: absolute;
width: 100px;
}
#mydivheader {
background: #9494fd;
}
#mydivheader > button {
margin-top: 20px;
width: 100%;
}
</style>
</head>
<body>
<div>
<button onClick="createDiv()"> create </button>
</div>
</body>
<script>
function createDiv() {
const counter = document.getElementsByClassName('myDiv').length;
let dom = '<div id="mydivheader" class = "Filter"><button>test '+counter+'</button></div>';
let myDiv = document.createElement("div");
myDiv.id = 'myDiv';
myDiv.className = 'myDiv';
myDiv.innerHTML = dom;
document.body.appendChild(myDiv);
myDiv.addEventListener('click', dragElement(myDiv), true);
}
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
/* if present, the header is where you move the DIV from:*/
document.getElementById(elmnt.id + "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>

Related

Making a html element that acts like a window

I'm trying to make a window-like HTML element that functions like window.open but only works within the bounds of the page.
I've run into 3 problems:
The first being that I don't know how to change the size of it
How to open and close it I want to click on Icon and make it open and also how to close it. It's already draggable so that the one thing going for it.
How to set the initial position of it. if anyone has a better method cause I'm still super new to coding and just got this off of W3schools anything would be useful.
This is what I want my end goal to look like
//Make the DIV element draggagle:
dragElement(document.getElementById("mydiv"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
/* if present, the header is where you move the DIV from:*/
document.getElementById(elmnt.id + "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;
}
}
Size - to change the size of an element you can simply edit the its style.width and style.height. If you would like to have a draggable resizing cursor, like with a real window, you would need to create a transparent element that covers the resizing activation areas, and listen to its events like you listen to the window dragging.
Initial position - just like you set the dragged position, you can set an initial one.
As for the opening and closing, you would most likely need to restructure the app a bit and build some abstractions. Try to think of a way to have a createNewWindow function that accepts arbitrary HTML content and just shows a window. Within that function you would add a "header" to the content, add resizing areas, add close/minimize/maximize buttons, add the window to a global array of windows (so that you can display a bottom bar with window titles and unminimize when needed).
There's no single answer here, you can build an app like that in a million different ways. Focus on abstracting things away.

Resizable and Draggable custom dialog in blazor server side

I am working on Blazor components in Core 3.1. I need to make a custom draggable dialog in blazor using only javscript(without jquery-ui). Can someone help me in achieving this. I tried some fiddles but controls inside them are not working.
This is just a sample you can modify according to your requirements.
You can write this CSS in site.css or in the style tag
<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>
In your blazor component
#page "/"
#inject IJSRuntime JsRuntime;
<h1>Draggable DIV Element</h1>
<div id="mydiv">
<div id="mydivheader">Header</div>
<p>This is only one sample</p>
</div>
#code {
protected override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
JsRuntime.InvokeVoidAsync("blazorjs.dragable");
return base.OnAfterRenderAsync(firstRender);
}
}
You write this any JavaScript (.js) file or in the script tag
<script>
window.blazorjs = {
dragable: function () {
dragElement(document.getElementById("mydiv"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
/* if present, the header is where you move the DIV from:*/
document.getElementById(elmnt.id + "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>
You can check code in blazorfiddle, https://blazorfiddle.com/s/uwjknuwx
I just copied from w3schools and implemented in blazor, https://www.w3schools.com/howto/howto_js_draggable.asp

Javascript code getElementByID with C# loop

I'm trying to use draggable HTML/JS on my code, but I get an issue when I try to loop over each element.
I don't overcome to convert my code from a single element to a foreach loop.
This is my code:
# CSS CODE
<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>
# HTML CODE
<div id="mydiv">
<div id="mydivheader">
Firstname Lastname
</div>
</div>
# JAVASCRIPT CODE
<script>
//Make the DIV element draggagle:
dragElement(document.getElementById("mydiv"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
/* if present, the header is where you move the DIV from:*/
document.getElementById(elmnt.id + "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>
It works for one element like the example above.
But I would like to loop like this:
# HTML CODE
#foreach (var player in Model.PlayersToMatchs)
{
<div id="mydiv#(player.Player.PlayerID)">
<div id=" mydivheader#(player.Player.PlayerID)">
#player.Player.Firstname #player.Player.Lastname
</div>
</div>
}
I tried to modify my Javascript part by changing the first line to take into account the partial id:
dragElement(document.querySelector('[id^="mydiv"]').id);
But How I can rewrite this part:
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
/* if present, the header is where you move the DIV from:*/
document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
} else {
/* otherwise, move the DIV from anywhere inside the DIV:*/
elmnt.onmousedown = dragMouseDown;
}
Thank you !
As Heretic Monkey said, querySelector only returns the first element, you need to use querySelectorAll to get all elements and then loop the elements array to call the dragElement function.
var elements = document.querySelectorAll('[id^="mydiv"]');
elements.forEach(element=> {
dragElement(element);
}
);

resizable and draggable div with fixed surface area

Is it possible to make a resizable and draggable div with a fixed surface area?
Example: I have a square div with a surface area of 10000px² (100 x 100px) and then I change the width (with the mouse on the corner or on the edge) to 50px, the heigth should now change automaticly to 200px so the surface area stays 10000px².
Then I´d like to drag it all over the page, resize it again etc...
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-
ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-
ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#draggable { width: 100px; height: 100px; padding: 0.5em; border:
1px solid;}
</style>
<script>
$(function() {
$( "#draggable" ).draggable().resizable();
});
</script>
</head>
<body>
<div id="draggable" class="ui-widget-content">
<p>Drag me around</p>
</div>
</body>
</html>
ok, so here is the code, I have resizable and draggable div but now I need the fixed surface area (eg 10000px²) as I mentioned before...
you can use jquery's UI to do all of this.
use http://jqueryui.com/draggable/ to allow for dragging,
use http://jqueryui.com/resizable/ to allow for resizing
using the resize event, you can have jquery modify the div so it will follow any height/width rules you want.
Try this:
(function(draggable) {
var elm = document.getElementById(draggable);
elm.onmousedown = drag;
function stop() {
document.onmouseup = null;
document.onmousemove = null;
}
function drag(e) {
if (e.target == elm) {
var absX = e.clientX;
var absY = e.clientY;
var left = parseInt(getComputedStyle(elm).left, 10);
var top = parseInt(getComputedStyle(elm).top, 10);
var relX = absX - left;
var relY = absY - top;
document.onmouseup = stop;
document.onmousemove = function(e) {
var absX = e.clientX;
var absY = e.clientY;
elm.style.left = absX - relX + "px";
elm.style.top = absY - relY + "px";
}
}
}
})("box");
(function(resizeable) {
var elm = document.getElementById(resizeable);
var wHandler = elm.childNodes[1];
var hHandler = elm.childNodes[3];
wHandler.onmousedown = resizeW;
hHandler.onmousedown = resizeH;
function stop() {
elm.style.cursor = "";
document.body.style.cursor = "";
document.onmouseup = null;
document.onmousemove = null;
}
var w = 100;
var h = 100;
var area = w * h;
function resizeW(e) {
elm.style.cursor = "w-resize";
document.body.style.cursor = "w-resize";
var left = parseInt(window.getComputedStyle(elm, null)["left"], 10);
document.onmouseup = stop;
document.onmousemove = function(e) {
var absX = e.clientX;
var width = absX - left;
var height = area / width;
elm.style.width = width + "px";
elm.style.height = height + "px";
}
}
function resizeH(e) {
elm.style.cursor = "n-resize";
document.body.style.cursor = "n-resize";
var top = parseInt(window.getComputedStyle(elm, null)["top"], 10);
document.onmouseup = stop;
document.onmousemove = function(e) {
var absY = e.clientY;
var height = absY - top;
var width = area / height;
elm.style.height = height + "px";
elm.style.width = width + "px";
}
}
})("box");
Fiddle
Though there's a small bug, I think. Couldn't fix it. When you resize the width it's ok, but when you resize the height, and then move the div, it lags or w/e. Check the fiddle. Other than this, it's working fine.

Javascript: Dragable Element Messed up When There is <select> in Element

I am implementing the code that I get from internet and I put a select on it.
The element is messed up when I do this step on Chrome browser;
I move the element and drag it.
I choose select and then the element is moving to left top page.
Please help, just simply copy and paste this code to your editor and run it;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
<script type="text/javascript">
//object of the element to be moved
_item = null;
//stores x & y co-ordinates of the mouse pointer
mouse_x = 0;
mouse_y = 0;
// stores top,left values (edge) of the element
ele_x = 0;
ele_y = 0;
//bind the functions
function move_init()
{
document.onmousemove = _move;
document.onmouseup = _stop;
}
//destroy the object when we are done
function _stop()
{
_item = null;
}
//main functions which is responsible for moving the element (div in our example)
function _move(e)
{
mouse_x = document.all ? window.event.clientX : e.pageX;
mouse_y = document.all ? window.event.clientY : e.pageY;
if(_item != null)
{
_item.style.left = (mouse_x - ele_x) + "px";
_item.style.top = (mouse_y - ele_y) + "px";
}
}
//will be called when use starts dragging an element
function _move_item(ele)
{
//store the object of the element which needs to be moved
_item = ele;
ele_x = mouse_x - _item.offsetLeft;
ele_y = mouse_y - _item.offsetTop;
}
</script>
</head>
<body onload="move_init();">
<div id="ele" onMouseDown="_move_item(this);" style="width:100px; height:100px; background-color: gray; position:fixed;">
<select onmousedown="">
<option>Oh</option>
<option>Yes</option>
<option>No</option>
</select>
</div>
</body>
</html>
Would you please help me to fix the code...
var draggable = function(element) {
element.addEventListener('mousedown', function(e) {
e.stopPropagation();
// if the current target is different (in the case of a child node), don't drag.
// you can customize this to specify types of children which prevent dragging
if (e.target != element)
return;
var offsetX = e.pageX - element.offsetLeft;
var offsetY = e.pageY - element.offsetTop;
function move(e) {
element.style.left = (e.pageX - offsetX) + 'px';
element.style.top = (e.pageY - offsetY) + 'px';
}
function stop(e) {
// remove the event listeners on the document when not dragging
document.removeEventListener('mousemove', move);
document.removeEventListener('mouseup', stop)
}
document.addEventListener('mousemove', move)
document.addEventListener('mouseup', stop)
})
}
function init() {
var ele = document.getElementById('ele');
draggable(ele)
}
This may not work in some IE versions, but you should be able to add the necessary fixes for that. Here's the fiddle http://jsfiddle.net/seKbz/2/

Categories

Resources