fancytree drag n drop node revert back to original position - javascript

How do you make a node in fancytree revert back to it's original position after being dragged to a new place in the tree, for example after dropping the node to a new position I would have a confirmation dialog yes or no to move the object if the user says no it reverts back so in the drop there needs to be a move to a new destination shown but also have the confirmation and revert back yes or no. Or on drag start get the position and on drag drop revert to original position
$("#tree").fancytree({
extensions: ["dnd"],
// .. other options...
dnd: {
autoExpandMS: 400,
draggable: { // modify default jQuery draggable options
zIndex: 1000,
scroll: false,
containment: "parent",
revert: "invalid"
},
preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
dragStart: function(node, data) {
// This function MUST be defined to enable dragging for the tree.
// Return false to cancel dragging of node.
// if( data.originalEvent.shiftKey ) ...
// if( node.isFolder() ) { return false; }
return true;
},
dragEnter: function(node, data) {
return true;
},
dragExpand: function(node, data) {
// return false to prevent auto-expanding data.node on hover
},
dragOver: function(node, data) {
},
dragLeave: function(node, data) {
},
dragStop: function(node, data) {
},
dragDrop: function(node, data) {
// revert node to back to it's original place
data.otherNode.moveTo(node, data.hitMode);
}
}
});

It's been a while since I've worked in fancytree, so I don't know the full details, but I think I can come up with an idea that might work:
When dropping your node, you should do 2 actions:
Persist your original position in node.data (node.data.prevParent = node.parent() or prevSibling if you want to keep the position in the siblings)
Fire off your dialog with your 2 options and pass the node reference
Your dialog basicly has 2 options:
Accept: delete node.data.prevParent and close the dialog
Reject: retrieve node.data.prevParent and move the node as a new child/sibling. Close the dialog afterwards
I hope this helps out a bit. Just in case you haven't found it: This also helps: fancytree documentation

Related

ACE change key binding conditionally

If the user presses the down key while a custom popup is displayed, I would like this down event to be cancelled from the editor and handled manually.
However, if the popup is disactivated, the 'down' key should perform as usual.
For that, I wrote this:
editor.commands.addCommand({
name: 'nav_down.',
bindKey: {win: 'Down', mac: 'Down'},
exec: function(editor) {
if(myPopupIsOpen()) {
// Do whatever I want with the popup.
return false;
} else {
// just leave the key.
return true;
}
readOnly: true
});
Unfortunately, I can return false or true, the result is the same, it always capture the down event, which is annoying. How can I prevent that?
I already tried the following:
Add a key binding to the DOM. But after that, the interaction always happen (i.e. I cannot capture it).
Return false or true as suggested for common events but this does not work here.
EDIT
The solution from #a user works very well.
Instead of the above command, I wrote:
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
keyboardHandler = new HashHandler();
keyboardHandler.addCommand({
name: 'nav_down.',
bindKey: {win: 'Down', mac: 'Down'},
exec: function(editor) {
if(myPopupIsOpen()) {
// Do whatever I want with the popup.
return true; // CHANGE HERE ! true is when it capture it.
} else {
// just leave the key.
return false; // CHANGE HERE ! false is when I don't capture it.
}
readOnly: true
});
editor.keyBinding.addKeyboardHandler(keyboardHandler);
In the current version ace only keeps one command for each key so your addCommand call removes default binding for down.
You can add new keyboard handler similar to what autocompletion does https://github.com/ajaxorg/ace/blob/v1.1.3/lib/ace/autocomplete.js#L221
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
keyboardHandler = new HashHandler();
keyboardHandler.addCommand(/*add your command with return false*/)
editor.keyBinding.addKeyboardHandler(keyboardHandler);

Attaching contextMenu to flot graph points

I am trying to attach the jQuery plugin contextMenu to the points in a flot graph. I have the right click context menu working using the following code:
$(".chart").bind("plotclick").contextMenu('myMenu1', {
bindings: {
'delete': function(t) {
// Do stuff when delete is clicked
}
}
});
With the above, if I right click on any of the points on the graph a little menu pops up with "DELETE" in it.
However I need access to the data provided by flot about the point that was clicked. Normally the plotclick function would look like this:
$(".chart").bind("plotclick", function (event, pos, item) {
// In here I can see details about the point that was clicked by looking at event, pos and item
})
So my question is, how do I pass the event, pos, item variables through to the delete function of the contextMenu in my first code above? Is what I'm doing even the right way to attach the contextMenu?
Thanks
How about your bind the context menu generically to the plot container div and then use the plothover event to keep track of whether or not you are "over" a point? If you aren't over a point, you suppress the pop-up, if you are over one you get the point information from a global-scoped variable.
$("#placeholder").contextMenu('myMenu1', {
onContextMenu: function(e) {
if (somePoint) return true;
else return false;
},
bindings: {
'delete': function(t) {
alert(lastPoint.series.label);
}
}
});
var somePoint = null, lastPoint = null;
$("#placeholder").bind("plothover", function (event, pos, item) {
if (item){
somePoint = item;
}else{
lastPoint = somePoint;
somePoint = null;
}
});
Fiddle here.
BTW, the reason my original fiddle didn't work, was I had the wrong jquery context menu. I thought you were using this one not this one.

revert mootools sortable move

I'm using mootools sortable to handle a simple image gallery function. If you move the image from the left column to the right column, the photo is added into the user's "photos" table by a storeImage call in the onComplete event.
Here's a simple fiddle of it: http://jsfiddle.net/JQja3/1/
My question is, if the storeImage call from the onComplete event fails, how can I revert the image back to the "available" left stack?
you need to store the groups and parents in a var and then revert, this will totally restore the old group and order.
this pattern will create a restore function that can undo it - every time.
http://jsfiddle.net/JQja3/6/
new Sortables('#example2 UL', {
clone: true,
revert: true,
opacity: 0.7,
onStart: function(el, clone) {
this.restore = (function() {
var oldParent = el.getParent(),
oldList = oldParent.getChildren();
return function() {
oldParent.adopt(oldList);
}
})();
},
onComplete: function(el, clone){
var storeImage = false; // this is false to simulate a bad return from the DB store call
if (!storeImage){
this.restore();
}
}
});

Script.aculo.us Drag 'n' Drop - Revert onEnd condition

I'm trying to revert a draggable if a condition returns false. So for instance, I'd like to do the following:
new Draggable('myelement', {
onStart: function() {
// do something
},
onEnd: function() {
var condition = getConditionVal();
if (!condition) revert to original position
else {
// do something else
}
}
});
Would this be possible? Not sure if "droppables" would work in this case since the droppable area changes dynamically.
Scriptaculous drag/drop is designed to have all kinds of fancy stuff easily added.
Of course you can edit the revert option any time.
To change the value of the revert-option of an draggable, just reset the revert-option:
var myDraggable = new Draggable('myelement', {
onStart: function() {
// do something
},
onEnd: function() {
var condition = getConditionVal();
if (!condition){
myDraggable.options.revert = true;
}
else {
myDraggable.options.revert = false;
// do something else
}
};
});
Scriptaculous does the revert right after the onEnd event call,
which gives us the possibility of changing it before it will be executed.
Scriptaculous's drag/drop code wasn't designed to have conditional revert. You can have revert or no revert. That's all, sadly.
This feature has been requested many times but scripty/prototype has waned in popularity over the years, so it's doubtful this feature will ever be added.

Interested in tracking the events that get fired while user browses a site

I was wondering if it's possible to do as follows:
In my site I am using a lot of jQuery plugins that fire different events that I don't know about.
Is there a way - a program, a browser add-on, or something else - that I can browse the site and get a list of the exact javascript events that were fired with every click?
For example, I have a jQuery plugin that when I right click on any element a custom contextMenu shows and then when I click on one of the options other things come up. I need to know exactly what Javascript basic events were fired:
$('input:submit, button:submit').rightClick(function (e) {
$(this).contextMenu('contextMenuInput', {
'Capture This': {
click: function (element) { // element is the jquery obj clicked on when context menu launched
doSomething();
},
klass: "kgo" // a custom css class for this menu item (usable for styling)
},
'Create List': {
click: function (element) {
},
klass: "kfilter kdisabled"
},
'Collect Data': {
click: function (element) {
},
klass: "kcapture kdisabled"
}
},
{ disable_native_context_menu: true }
);
});
Does anyone have any idea?
You can use the following code to show events currently bound ....
here is an example of using this code : http://jsfiddle.net/manseuk/CNjs3/
(function($) {
$.eventReport = function(selector, root) {
var s = [];
$(selector || '*', root).andSelf().each(function() {
var e = $.data(this, 'events');
if(!e) return;
s.push(this.tagName);
if(this.id) s.push('#', this.id);
if(this.className) s.push('.', this.className);
for(var p in e) s.push('\n', p);
s.push('\n\n');
});
return s.join('');
}
$.fn.eventReport = function(selector) {
return $.eventReport(selector, this);
}
})(jQuery);
Use it like this ->
// all events
alert($.eventReport());
// just events on inputs
alert($.eventReport('input'));
// just events assigned to this element
alert($.eventReport('#myelement'));
// events assigned to inputs in this element
alert($.eventReport('input', '#myelement'));
alert($('#myelement').eventReport('input')); // same result
// just events assigned to this element's children
alert($('#myelement').eventReport());
alert($.eventReport('*', '#myelement'); // same result
Updated as per comments
If you want to see what is bound to these events this is an excellent tool -> http://www.sprymedia.co.uk/article/Visual+Event
It's not quite what your looking for, but with firebug, you can log events for a given DOM element.
You can do this by right clicking on the element in the html tab and clicking log events:
The event log:
You may also find the firebug extension "EventBug" useful:
http://getfirebug.com/wiki/index.php/Firebug_Extensions#Eventbug
http://www.softwareishard.com/blog/firebug/eventbug-alpha-released/

Categories

Resources