I’ve been coding this selection system that allows me to select widgets and drag a bunch of them, the problem is that when I select two widgets and I drag the other widget that’s not selected, they’re all being dragged, I don’t want that to happen.
What is supposed to happen is that when I put my mouse down on a non-selected widget, all of the selected widgets have to not be selected anymore (that means the ".selected" class is removed). The problem is that I’m confused on how to apply this only to the non-selected widgets, it has to not apply to selected widgets.
Here is the code before I tried:
<!DOCTYPE html>
<html>
<head>
<style>
#selection-rectangle {
position: absolute;
border: 2px dashed blue;
pointer-events: none;
display: none;
z-index: 9999999;
}
.widgets.selected {
outline-color: blue;
outline-width: 2px;
outline-style: dashed;
}
</style>
</head>
<body>
<div id="widget1" class="widgets" style="left: 50px; top: 50px;">
<div id="widget1header" class="widget-header"></div>
</div>
<div id="widget2" class="widgets" style="left: 150px; top: 150px;">
<div id="widget2header" class="widget-header"></div>
</div>
<div id="widget3" class="widgets" style="left: 250px; top: 250px;">
<div id="widget3header" class="widget-header"></div>
</div>
<script>
let isSelecting = false;
let selectionStartX, selectionStartY, selectionEndX, selectionEndY;
let selectionRectangle;
let draggedElements = [];
const widgets = document.querySelectorAll('.widgets');
const widgetContainer = document.getElementById('widget-container');
document.addEventListener('mousedown', (event) => {
const header = event.target.closest('.widget-header');
if (header) {
const widget = header.parentElement;
draggedElements = Array.from(widgets).filter((widget) => widget.classList.contains('selected'));
draggedElements.forEach((widget) => {
const shiftX = event.clientX - widget.getBoundingClientRect().left;
const shiftY = event.clientY - widget.getBoundingClientRect().top;
function moveElement(event) {
const x = event.clientX - shiftX;
const y = event.clientY - shiftY;
widget.style.left = x + 'px';
widget.style.top = y + 'px';
}
function stopMoving() {
document.removeEventListener('mousemove', moveElement);
document.removeEventListener('mouseup', stopMoving);
}
document.addEventListener('mousemove', moveElement);
document.addEventListener('mouseup', stopMoving);
});
return;
}
const isWidgetClicked = Array.from(widgets).some((widget) => {
const widgetRect = widget.getBoundingClientRect();
return (
event.clientX >= widgetRect.left &&
event.clientX <= widgetRect.right &&
event.clientY >= widgetRect.top &&
event.clientY <= widgetRect.bottom
);
});
if (!isWidgetClicked && event.target !== selectionRectangle) { // Check if the target is not the selection rectangle
isSelecting = true;
selectionStartX = event.clientX;
selectionStartY = event.clientY;
selectionRectangle = document.createElement('div');
selectionRectangle.id = 'selection-rectangle';
selectionRectangle.style.position = 'absolute';
selectionRectangle.style.border = '2px dashed blue';
selectionRectangle.style.pointerEvents = 'none';
selectionRectangle.style.display = 'none';
document.body.appendChild(selectionRectangle);
// Remove selected class from widgets
widgets.forEach((widget) => {
widget.classList.remove('selected');
});
}
});
document.addEventListener('mousemove', (event) => {
if (isSelecting) {
selectionEndX = event.clientX;
selectionEndY = event.clientY;
let width = Math.abs(selectionEndX - selectionStartX);
let height = Math.abs(selectionEndY - selectionStartY);
selectionRectangle.style.width = width + 'px';
selectionRectangle.style.height = height + 'px';
selectionRectangle.style.left = Math.min(selectionEndX, selectionStartX) + 'px';
selectionRectangle.style.top = Math.min(selectionEndY, selectionStartY) + 'px';
selectionRectangle.style.display = 'block';
widgets.forEach((widget) => {
const widgetRect = widget.getBoundingClientRect();
const isIntersecting = isRectangleIntersecting(widgetRect, {
x: Math.min(selectionStartX, selectionEndX),
y: Math.min(selectionStartY, selectionEndY),
width,
height,
});
if (isIntersecting) {
widget.classList.add('selected');
} else {
widget.classList.remove('selected');
}
});
}
});
document.addEventListener('mouseup', () => {
if (isSelecting) {
isSelecting = false;
selectionRectangle.remove();
}
});
function isRectangleIntersecting(rect1, rect2) {
return (
rect1.left >= rect2.x &&
rect1.top >= rect2.y &&
rect1.right <= rect2.x + rect2.width &&
rect1.bottom <= rect2.y + rect2.height
);
}
</script>
<style>
.widgets {
position: absolute;
z-index: 9;
background-color: #000000;
color: white;
font-size: 25px;
font-family: Arial, Helvetica, sans-serif;
border: 2px solid #212128;
text-align: center;
width: 500px;
height: 200px;
min-width: 166px;
min-height: 66px;
overflow: hidden;
resize: both;
image-resolution: none;
border-radius: 10px;
}
.widget-header {
padding: 10px;
cursor: move;
z-index: 10;
background-color: #040c14;
outline-color: white;
outline-width: 2px;
outline-style: solid;
}
</style>
<script>
// Make the DIV element draggable:
dragElement(document.getElementById("widget1"));
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;
}
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;
}
}
// Make the DIV element draggable:
dragElement(document.getElementById("widget2"));
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;
}
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;
}
}
// Make the DIV element draggable:
dragElement(document.getElementById("widget3"));
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;
}
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>
I tried creating a function that checks if a div is selected or not, if not, when the mouse is down on it, it unselects everything else.
It didn’t work for some reason
2
Answers
add this line and remove dragElement function
Remove your second
<script>
tag, its content is repeated and unnecessary. In the mousedown handler, check if the clicked widget hasselected
class or not and add todraggedElements
accordingly.