I have a user interface where some properties are represented as draggable items, and they can be dragged off a toolbar and dropped on some receiving item which is then updated. For this I'm using the Dojo Drag and Drop. I have some Dojo Dnd Sources, Targets, several accept types, everything is working great.
Except that I don't want to actually move or copy the nodes of the sources to the targets. When the drop occurs I simply want to fire an event handler so I can modify the target in question, or make other updates in the UI as appropriate.
What is the best way to do this?
I've tried variations on a null creator function, calling cancel in an onDrop handler, removing the nodes that are passed to the onDrop handler from their parent, but none of these avenues seemed to work or be workable.
Thanks for any assistance.
I just wrote this code which does what you want. (Though it seems you've tried something similar that didn't work?)
// Gobble up dropped nodes
target.on(
"Drop",
lang.hitch(
target,
function( source, nodes, copy )
{
this.selectAll().deleteSelectedNodes();
}
)
);
Related
Disclaimer: This is more an architectual question.
I am trying to build a quite simple UI. I have two lists of elements, all elements in boths lists are of the same type. If I drag one element from the left to the right onto an element of this list, I want to execute a POST call to the backend sending both data-obj-id attribute values along.
I settled on InteractJS and HTMX but its f**** hard to build something like this.
My approach: I need to fire some kind of event to trigger the HTMX POST call. But the event needs to know which elements are being dropped on each other. So I need a custom event (not possible to get the drop event anyway), which contains the ID of the other element.
I tried:
const newEvent = new Event('interactjs:drop-'+draggableElement.getAttribute('data-obj-id'));
document.body.dispatchEvent(newEvent);
<div data-obj-id="{{ my_obj.id }}"
hx-post="/my-post-call"
hx-trigger="interactjs:drop-{{ my_obj.id }} from:body">...</div>
But the moment the event contains a number, it's not recognised anymore. I guess I just chose a poor choice of architecture to solve my problem?
Thx!
I want to check the list of event listeners that are added. For example, I used the code cy.on('pan zoom resize', update); and added function called update in for loop. I do this many times. I also call cy.off('pan zoom resize', update); to remove the event listeners but I want to be sure about it.
The only think I can think of is using console.log but this method might not be helpful.
I also think that in some places people forgot to remove the event listeners and just always added. With too many repetitions this might cause problems.
There is a data field in the private cytoscape object called listeners. You can see that if you:
console.log() the cy object,
navigate to _private,
then open the emitter object
and lastly go to listeners
This is the array listing all the default and user defined event listeners with some metadata like the event, type and scope of the listener.
You can access this in your code by simply calling
cy.emitter().listeners
The question now is, why do you need this information in the first place? Normally, you should be just fine if you call cy.off('eventXY', ...) before using any cy.on('eventXY', ...). Are you sure you need this for your application to work? Maybe elaborate more on the core problem (why you want these information in the first place).
Thanks and have a great day!
Looking to find where we can insert our own data for triggered events.
I have an extension that use to call onImpl(events, selector, data, callback), but that was back in 2.3.7. What is the updated way to add my event data if I want to pass data that can be used with the event?
As far as I know, it is not possible to pass data to core events anymore. But you can do it when you emit the events programmatically.
I'm assuming this is the extension that you mentioned. If you just want the paz/zoom functionality, you can use the pan-zoom extension.
I'm not sure if a toolbar extension would be any useful. The customization of the toolbar with an extension would be very limited. You can create a fancy toolbar, style and position it as you like and connect the buttons with Cytoscape events with jQuery or other similar libraries.
P.S: instead of passing the data to the event, you may keep the data in a global variable and access it from callback function.
I got a question to which I have no answer after a couple of hours of trying and googling :(
I've created three dojo.dnd.Source components. It is used to couple a user to a project so to the left I've got projects and to the right I've got my users and in the center I got a canvas. I set up the relevant creators and checkacceptance functions and all is well.
Onto the center canvas a user can drop a project which is shown as a div containing all related users as div elements. The other dndtype that can be dropped is the user type, in that case I want to empty the canvas and show all projects to which te dropped user is related. As soon as I drop a project or user on the canvas the creator function is called. The problem is that the creator function returns 1 element that should be dropped, if I drop a user I need to draw several elements onto the canvas so the creator method isn't fully covering this since it returns only one element.
To cope with the default behaviour I tried to manually add projects to the canvas and returning only one, I know it ain't pretty :S It's working but I'm confronted with strange behaviour, if I move a project on the canvas it is treated as a user in stead of a project.
Bottom line, is there a way that you guys know of to drop one item and create multiple. I was searching to trigger the drop event myself but to no avail.
Thanks!
The event you are looking for is Source's onDrop event. Check the API docs for some more events you could use: there is a onDropExternal and onDropInternal for use inside and between Stores.
require(["dojo/dnd/Source"], function(Source){
var source = new Source({
onDrop = function(source, nodes, copy) {
//called only on the current target, when drop is performed
this.inherited(arguments); //execute the default onDrop function
//now add the node(s) to the other stores here
//you might be able to just do something like:
source2.insertNodes(nodes);//but this is untested ;)
}
});
});
Question:
Given a DOJO TreeGrid, how can I capture the event when a user clicks the expando ("+") button to expand a row, and store the specific row number or associated item's identifier? I'd like to do this for the express purpose of completely deleting the TreeGrid from the DOM, rebuilding it, and restoring it's state once rebuilt (i.e. programmatically expanding the rows that the user has previously expanded).
Background:
So I've got a custom DOJO TreeGrid, hooked up to a custom QueryReadStore, in my app. It was constructed using the following tutorial:
http://www.ibm.com/developerworks/web/library/wa-dojotreegrid/index.html?ca=drs-
Pretty interesting tutorial, but it might be irrelevant to my question because it doesn't really squash any functionality, it only seems to augment it.
Anyway, googling around for a moment, I found a nice function in the DOJO forums that I can use to programmatically expand a row, given the specific row index. Works perfectly.
The problem is that I haven't been able to find a good way to capture the expando click event, and relate it to a specific "parent item row" index in the grid.
Details aside, I'd like to get the row index of every row that the user has expanded, into an array (and delete the index of a row that the user collapses, obviously), so I can destroy this TreeGrid, and faithfully rebuild it, with the user's selections expanded properly.
I'm not really a novice to DOJO, but I'm certainly no expert by any means. I've done a fair bit of googling, and FireBugging, and haven't really been able to find anything that I can use to do this.
Suggestions? Anybody done something similar before? Stupid question with obvious answer that I've missed? I'm totally misguided and am going about it all wrong? Thanks everybody!
Something similar to this would probably work, this is how the dijit.Tree implementation wouldve looked;
var expandedNodes = {}
dijit.tree._onExpandoClick = function (args /* object wrap for args.node */) {
var treeNode = args.node,
path = treeNode.getTreePath(),
id = treeNode.getIdentity();
expandedNodes[id] = path;
}
I am not 100% sure im being strictly correct but for the TreeGrid you will have to look through code of dojox/grid/_TreeView.js (link). The _setOpen would be an entrypoint from which you can 'hook' the onclick action. from there, find the expandoCell.openStates hash, this is a true/false variable set, indexed by itemId. This hash is most likely what you need as your state