Make element draggable when child element is dragged - javascript

I have multiple programmatically created span elements designed to look and act like windows. Each element has a title bar running across the top. I am trying to get it so that the draggability is activated either by or only if the mouse is over the child title element using jQuery UI, is this possible?

It's possible. When the mouse hold the child element, make the parent element draggable, then make it not draggable again when mouse realizes it.
// The parent element
var $aa = $("#aa"),
// The child element
$bb = $("#bb");
// When the mouse is down
$bb.mousedown(function() {
// Drag the element
$aa.draggable();
});
// When the mouse realizes
$bb.mouseup(function() {
// Don't drag the element
$aa.draggable('destroy');
});
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js" integrity="sha256-xI/qyl9vpwWFOXz7+x/9WkG5j/SVnSw21viy8fWwbeE=" crossorigin="anonymous"></script>
<div id="aa">
---
<div id="bb">Push me</div>
</div>
This could improve with more events, anyway.

Related

Get vue component from event

I am building a drag and drop feature in my application where the drop area looks like this:
<template>
<div class="layers-panel" #dragover="onDragOver" #drop="onDragDrop">
<layer
v-for="(layer, index) in layers"
:key="layer.name"
:info="layer"
:offset="index"
ref="layer"
></layer>
</div>
</template>
Then the draggable items look like this:
<template>
<div class="layer" draggable="true" #dragstart="onDragStart">
<!-- Content of draggable element -->
</div>
</template>
In my drag over event, I want to get the current component that the element relates to, so when I drag an item over the <div class="layer"...> element I would like to get that component. I am not sure how to get access to this since an event is passed to the #dragover="onDragOver" event which only gives me access to html elements and not Vue components.
This is what my current dragover event looks like:
public onDragOver(evt: DragEvent) {
evt.preventDefault()
if (!evt.target) return
let layer = (evt.target as HTMLElement).closest('.layer') as HTMLElement
}
How can I get the component that that element belongs to?
Vue certainly allows you to access a component instance however I don't think it's necessary to reaching your actual goal: reordering of components via drag-and-drop.
Drag-and-drop means we're limited by what's afforded by DragEvent:
We can access the target element e.g. the element being dragged or dropped on
We can set arbitrary data via DataTransfer
You can't determine where the element is dropped because your drop element contains all the layers. Instead if each layer is a drop element, then you can determine which one it is via dragover via event.target.
We also need to identify which element corresponding to the layers array we're dragging/dropping on. This can be achieved by binding the index of each layer as an attribute so we can access it via event.target.
To keep it simple, I'll use the id attribute so I can just access it later via event.target.id:
<div
v-for="(layer, idx) in layers"
:key="idx"
:id="idx"
draggable="true"
#dragstart="dragstart"
>
<div
:id="idx"
class="draggable"
#dragover="dragover"
#drop="drop"
>
{{ layer }}
</div>
</div>
Note I bind the same index to id so I can correctly identify the target layer.
We'll also need to ensure we can identify the element that was dragged since on drop we'll only have the drop element via event.target. We can do this by setting data in DataTransfer when we first start the drag:
dragstart(event) {
event.dataTransfer.setData("selectedIdx", event.target.id);
},
Now on drop we have access to both and can manipulate layers as we desire:
drop(event) {
var selectedIdx = event.dataTransfer.getData("selectedIdx");
var targetIdx = event.target.id;
var selected = this.layers.splice(selectedIdx, 1)[0];
this.layers.splice(targetIdx, 0, selected);
},
Example codepen

How to get id of an element when clicked on it - javascript

I am developing a canvas application on which a user can draw various shapes. Various elements are drawn using d3.js. I want to use jsplumb to connect two SVG elements for which I need the id of each element when it is clicked on. Each element has an id that is generated by code when it is drawn and thus I don't know it before hand.
Is there a javascript implementation by which I can get the id of the elements on which I click? I wouldn't preferably want to add '' on each element that is being drawn on the canvas.
Can anyone suggest a way to do this?
You can use something like this
<script type='text/javascript'>
doClick = function (sender){
alert(sender.id);
}
</script>
<div id='a1' onclick='doClick(this)'>div1</div>
<div id='a2' onclick='doClick(this)'>div2</div>
https://jsfiddle.net/dy47dbvp/3/
You can simply access an element's ID using that element's attributes
var elemID = droppedElement.attr('id');
To get the id of the clicked Element:
$('#container').on('click', '.droppedElement', function (e) {
var elemID = droppedElement.attr('id');
}
The container is your canvas id and the droppedElement is the variable that captures the svg element or the clone of the svg element(if that is your case)

Add HTML Dynamically on Drag N Drop

A simple way to drag and drop html elements or content on a web page?
The goal is to drag the element and drop it on a container.
Once the element is dropped it will dynamically add html content based on its id.
To begin you will need to create an html page with the following code.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Drag N Drop Elements</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<!-- The element to be dragged and dropped -->
<span class="elements" id="paragraph">|Paragraph|</span>
<!-- The target for the dragged elements -->
<div id="document-section">This is the target for the drag n drop.</div>
<!--import javascript-->
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.2/jquery-ui.min.js"></script>
<script src="dragndrop.js"></script>
</body>
</html>
The following html in the example above is the element that you will be able to drag once completing all the javascript is added later on.
<span class="elements" id="paragraph">|Paragraph|</span>
Note: You can add other draggable elements by giving them the class elements and assigning a different id.
The next important element to discuss is the area on the page where the draggable elements are going to be dropped. To allow elements to be dropped in this area I have assigned it the id of #document-section that you will see used in the javascipt example later on.
Note: You don't have to use text in the div element below but make sure it has some width, height, and a border so that the user can see where to drop the element.
<div id="document-section">This is the target for the drag n drop.</div>
Next you will need to create a javascript file named dragndrop.js and place it in the same folder as the html file you created in the first step.
Javascript:
//store the id of the item being dragged
var dragging;
/*make all of the elements draggable*/
$(".elements").draggable({helper:"clone"});
/*on dragstart event for .elements*/
$(".elements").on("dragstart",function(){
//get the id of the element being dragged
dragging = $(this).attr("id");
});//end on dragstart event for .elements
//fire event when an element is dropped on #document-section div
$("#document-section").droppable({//begin droppable event
drop: function(event,ui) {//begin drop function
//switch case statement used to detect what element has been dropped
switch(dragging){//begin switch case
case "paragraph":
//array to hold the paragraph
var paragraph = [];
//if dragging variable equals "paragraph"
if(dragging === "paragraph"){//begin if then
//add the paragraph
paragraph.push('<p>Hello, I am a paragraph</p>');
//append the paragraph to your container I used #document-section in this example
$("#document-section").append(paragraph.join(""));
//set dragging to null to prevent duplicate elements being creating on drop
dragging = null;
break;
}//end switch case
}//end if then
}//end drop function
});//end droppable event
Once finished you should be able to drag the "paragraph" text on to the "This is the target for the drag n drop.", and see the results.

Mouseover on child element, not on parent

I'm implementing a highlight feature, which highlights the current hovered div and i have html structure something like this:
<div> <!-- this is the parent -->
<div> content ... </div><!-- a child -->
<div> content ... </div><!-- another child-->
</div>
how it should work:
- if i hover over the parent, then it should highlight the parent element.
- if i hover over a child element, the parent element's highlighting should fade and it should only highlight the child element
i'm using jquerys' mouseenter and mouseleaves events for that, the code looks like this
(actually its a bit different because im working with gwt and the native javascript interface, but it works the same way):
$(element).mouseenter(function(event)
{
showHighlightContainer();
});
$(element).mouseleave(function(event)
{
hideHighlightContainer();
});
the problem is: when i hover over the parent element, the element is beeing highlighted and everything is fine.
but when i hover over a child element, the child elemend AND the parent element are highlighted.
am i using the wrong mouse events? how could i solve that?
You need to use mouseover and mouseout
$(element).mouseover(function (event) {
event.stopPropagation();
showHighlightContainer();
}).mouseout(function (event) {
event.stopPropagation();
hideHighlightContainer();
});
Demo: Fiddle

How do you make text selectable on a jQuery draggable div?

I made a div draggable using jQuery. However, there is some text in that box, and I would still like to be able to copy and paste the text, but when I make an item draggable well when I click on the box it starts to move the box?
Use the cancel option when making the element draggable.
Prevents dragging from starting on specified elements.
$('.selector').draggable({ cancel: '.text' });
It doesn't make sense to allow dragging AND selecting text on the same element. However, if you keep thinking it's necessary, two things come to my mind:
Solution 1:
You can add a "handler" that will be the only child receiving the mouse down/up events to drag the div. For instance:
<div id="draggable">
<div class="handler"></div>
<div class="text">This is a selectable text</div>
</div>
And in your JavaScript code:
var draggableDiv = $('#draggable');
draggableDiv.draggable({
handle: $('.text', draggableDiv)
});
Solution 2:
You can disable the draggable thing when a user try to select text:
<div id="draggable">
<div class="text">This is a text</div>
</div>
And in your JavaScript code:
var draggableDiv = $('#draggable').draggable();
$('.text', draggableDiv).mousedown(function(ev) {
draggableDiv.draggable('disable');
}).mouseup(function(ev) {
draggableDiv.draggable('enable');
});
When someone tries to select something in .text, the draggable process is disabled.
The first solution is the proper one.
(As talked by the other 2 answers, but if you need an practical example, here it is (if I understood correctly): )
jsfiddle: Draggable demo
The point is to:_
add an extra child <span> as an dragHandler, in the (parent) <span> that you want to drag.
<span class="commentNt" id="commentDraggable_123">~//? was it not "single bounded context" in choreography?<br/>
<span class="dragHandler">Drag</span></span>
for the parent <span>, use following code to register that child <span> for dragging
(dragging will now only be triggered in child <span>'s region).
$('#commentDraggable_123').draggable({ handle: '.dragHandler' });
now, only dragging the child <span>, the whole parent <span> will then be dragged along with.
As for:
Q: Can I do this without introducing another child <span> inside the parent <span>?
ie: Can I just drag the "blank area", then the whole parent <span> is dragged;
while I drag on the "text area", the text can be selected instead of being dragged?
A: idk, I hope there is a way.

Categories

Resources