Hi I'm trying to develop a work flow editor as a drag, drop and draw, so that user can drag and drop shapes and connect them to create a diagram, for this I'm using Kendo UI draggable and drop target but the drop target has to be kendoDiagram widget. I'm facing issue in making the kendoDiagram as a dropTarget because it is already initialized as kendoDiagram please help me resolving this.
Thanks
function setDropTargetOnDiagram(element) {
$telerik.$(element).kendoDropTarget({
drop: function (e) {
var draggable = e.draggable,
element = e.dropTarget,
diagram = element.getKendoDiagram();
if (draggable && draggable.hint) {
var item = draggable.hint.data("data"),
offset = draggable.hintOffset,
point = new kendo.dataviz.diagram.Point(offset.left, offset.top),
transformed = diagram.documentToModel(point);
item.x = transformed.x;
item.y = transformed.y;
diagram.addShape(item);
}
}
});
}
Related
I'm adding a custom control that uses SVG to a Google Map.
After the map has been loaded and my control is shown, I need to grab the BBox from the svg element. Since I do not control when my element is attached to the DOM, I'm trying to find an event that will allow me to do the work in a callback.
Here's roughly what I have:
map = new google.maps.Map(...);
...
container = document.createElement("div")
svg = createAndDrawSVGElement(...); //this returns an svg element
container.appendChild(svg);
INSERT_THE_RIGHT_EVENT_HERE(function() {
var bbox = svg.getBBox();
... //bbox will be empty if svg isn't attached
}
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(container);
My current, ugly workaround is a setTimeout. I'd like something more predictable.
I was able to resolve this without an event, by attaching my SVG to a hidden DIV temporarily, so I can get the bbox.
Solution here: https://stackoverflow.com/a/45465286/62024
After looking at the API, I would try this (although the doc does not explicitely say whether this is called before or after attaching the element):
var map = new google.maps.Map(...);
...
var container = document.createElement("div")
var svg = createAndDrawSVGElement(...); //this returns an svg element
container.appendChild(svg);
var controls = map.controls[google.maps.ControlPosition.RIGHT_BOTTOM];
var position = controls.length;
google.maps.event.addListenerOnce(controls, "insert_at", function(i) {
if (i === position) {
var bbox = svg.getBBox();
... //etc
}
}
controls.insertAt(pos, container);
I'm new to EaselJS. I wonder how I can detect a drop of one container on another container in EaselJS.
So I want to get the dropped container in an eventlistener of the drop target container.
Any examples on this?
I could not find this in the drag drop examples of EaselJS.
Thanks
You can also use getObjectsUnderPoint. Here is a quick sample I put together.
http://jsfiddle.net/lannymcnie/6rh7P/1/
var targets = stage.getObjectsUnderPoint(stage.mouseX, stage.mouseY);
This is from another post asking a similar question. I also posted more info about it.
EaselJS: connect 2 containers/shapes using a line
In the pressmove or stagemouseup event, you can verify if the mouse position (stage.mouseX and stage.mouseY) if over the parent container. To do the verification, you can use the hitTest.
Notice that, hitTest will only if your parent container has at least one mouse event listener, which I think is a bug on EaselJS 0.7.1
I made this class on coffeescript to solve that problem:
class DragContainer
DragContainer.prototype = new createjs.Container()
DragContainer::Container_initialize = DragContainer::initialize
constructor: (opts) ->
#initialize opts
DragContainer::initialize = (opts) ->
#Container_initialize()
#droptargets = new Array()
#on 'mousedown', #handleMouseDown
handleMouseDown: (e) =>
#on 'pressup', (ev)=>
#removeAllEventListeners 'pressup'
if #droptargets and #droptargets.length > 0
#evaluateDrop e
evaluateDrop: (e) =>
target = null
dropped = false
for drop in #droptargets
pt = drop.globalToLocal stage.mouseX, stage.mouseY
if drop.hitTest pt.x, pt.y
target = drop
dropped = true
if dropped
#dispatchEvent {type: 'dropped', currentTarget: target}
else
#dispatchEvent {type: 'dropped', currentTarget: null}
The droptargets property is an array that keeps the objects you want to associate with the drop of your container.
I have an image loaded on the dom already, and I want to be able to drag that image into a canvas and drop it into the canvas and create a kineticjs object out of it.
I don't know how to make the image draggable, and I don't know how to make the canvas react to drag and drop events that already exist on the dom. Can someone show me how to do this?
Most of the tutorials show how to drag and drop from within the canvas, or the file system, I'm looking how to drag from the DOM to the canvas.
Background info:
I want to have a menu system or a bunch of thumbnails that a user can drag and drop into the canvas to expand the photo.
Thanks in advance!
No problem!
1 You have to use "drag and drop" from html5. Tutorial: http://www.html5rocks.com/en/tutorials/dnd/basics/
2 setup dom event to image:
var dragSrcEl = null;
//image
document.getElementById("yoda").addEventListener('dragstart',function(e){
dragSrcEl = this;
});
3 Events for container object:
var con = stage.getContainer();
con.addEventListener('dragover',function(e){
e.preventDefault(); // !!important
});
//insert image to stage
con.addEventListener('drop',function(e){
var image = new Kinetic.Image({
draggable : true
});
layer.add(image);
imageObj = new Image();
imageObj.src = dragSrcEl.src;
imageObj.onload = function(){
image.setImage(imageObj)
layer.draw()
};
});
And of course full example: http://jsfiddle.net/lavrton/n4w44/
I'm trying to prevent the dragging and dropping of nodes outside of the parent node ("LLCA") with no luck.
Any suggestions?
Image of Treeview
I ended up getting it to work using your code below:
function onDrop(e) {
var dst = e.destinationNode;
var first = $('.k-item:first');
var pos = e.dropPosition;
if (dst && dst.uid === first.uid && pos !== "over") {
e.setValid(false);
}
}
Lets define the treeview:
var tree = $("#tree").kendoTreeView({
dataSource :content,
dragAndDrop:true
}).data("kendoTreeView");
What I'm going to do is add a drop callback where I will control that:
We are not dropping outside the tree
We are not dropping before or after the first node of the tree
The definition of the tree would be:
var tree = $("#tree").kendoTreeView({
dataSource :content,
dragAndDrop:true,
drop :function (ev) {
var dst = tree.dataItem(ev.destinationNode);
var first = tree.dataItem(".k-item:first");
var pos = ev.dropPosition;
if (dst && dst.uid === first.uid && pos !== "over") {
console.log("invalid");
ev.setValid(false);
}
}
}).data("kendoTreeView");
Check http://docs.kendoui.com/api/web/treeview#drop for information on drop event.
Because I cannot comment on an answer, I will write my own.
User Mithrilhall asked about MVC wrappers, also the top answer only prevents movement to the root node.
I will attempt to answer both Mithrilhall and provide an example where you can only move a child within the context of its parent. To put it another way, to only allow children of any parent to change their order within the parent.
Firstly, for MithrilHall, this is how you get to the events in MVC.
#(Html.Kendo().TreeView()
.Name("ourTreeView")
.Events(e => e.Drop("treeViewDrop"))
There are other events in treeview, you can take a gander for yourself. The argument is the name of a javascript function. Here is an example javascript function for this MVC wrapper to prevent children from moving outside of their parent, but allowing them to still move within the parent.
<script type="text/javascript">
function treeViewDrop(dropEvent) {
var treeView = $("#ourTreeView").data("kendoTreeView");
var destination = treeView.dataItem(dropEvent.destinationNode);
var source = treeView.dataItem(dropEvent.sourceNode);
if (!(destination && destination.parentID == source.parentID)) {
dropEvent.setValid(false);
}
}
</script>
I had a parentID field modeled in my datasource. You could accomplish this in many ways. The dataItem method returns a kendo treeview item, so it has all of your modeled fields in it.
Also understand, this solution does not change the widget to show an X when you are moving to a place you cannot drop to. This is another problem with another solution.
I hope this helps, good luck!
After dojo drag and drop, once the page is submitted, I have to save the position of every item that has been placed into "targetZone". How can we save the position?
Eugen answered it here :
Dojo Drag and drop: how to retrieve order of items?
That would be the right way. If you look at the link above, you can save the resulting "orderedDataItems" object as a JSON ...
Look at the following function. It saves our DND "Lightbox" (dojo.dnd.source) to a JSON.
_it is the current raw dnd item
_it.data.item contains all your stuff you need to keep
in our case _it.data.item.label keeps the customized nodes (pictures, video, docs) as a string, we can use later to dojo.place it
it is the dnd item you want to save without dom nodes
E.g. if you drop items from a dijit tree to a arbitrary dojo dnd source / target:
_RAM or _S in our data.item we made before needs to be overwritten.
LBtoJson: function(){
var that = this;
var orderedLBitems = this.dndSource.getAllNodes().map(function(node){
var _it = that.dndSource.getItem(node.id);
var it = { data:{ item:{} }, label:'', type:'' };
if((_it.data.item._RAM)){_it.data.item._RAM={}}
if((_it.data.item._S)){_it.data.item._S={}}
it.data.item = dojo.clone(_it.data.item);
it.label = it.data.item.label[0]||it.data.item.label;
it.type = _it.type;
console.log( it );
return it;
});
var LBjson = dojo.toJson(orderedLBitems);
return LBjson;
}
By calling getAllNodes(), you'll receive a list of nodes in the order they are shown. So if you wanted to save a list in a specific order, you could do something similar to this:
var data;
var nodes = dndSrc.getAllNodes();
for(var i; i < nodes.length; i++)
{
data.push({id: nodes[i].id, order: i});
}
For more information about Dojo DnD regarding data submission, check out this article about DnD and Form Submission: http://www.chrisweldon.net/2009/05/09/dojo-drag-n-drop-and-form-submission