PDA

View Full Version : [SOLVED] How to cancel link navigation on aborted drop



yyogev
8 Aug 2009, 11:30 PM
Hi everyone,

I implemented drag-and-drop within a multi-grouping grid, where the rows represent issues in a bug tracking system. The user can drag using any point in a handle area which contains a drag handle icon (the 4-directional arrows cross), a 'work' link (set/reset 'work' keyword on issues), and a link to allow viewing of issue details in a separate page. see attached picture example. (the link is the issue ID)
http://extjs.com/forum/attachment.php?attachmentid=15514&stc=1&d=1249802574

The use case in question happens when a user starts to drag an issue using the link to the issue. The user aborts the drag, but does so by first dragging back to the original position (users often try to undo actions by bringing things to where they found them...). In doing so, the link receives the click event and the browser navigates to the issue.

I tried to cancel the navigation from the link on aborted drag, but whatever I tried the navigation still happened.

Here are the relevant code snippets:


// in header
var in_drag = 0;

// in issue renderer
var bug_link = "<A href='/bugs/show_bug.cgi?id=" + value + "' " +
// disable click from drag by link and drop in same position
"onClick='return in_drag == 1 ? false : true;' " +
">" + text +
"</A>";

// in drag handling code
var el = Ext.get(get_bug_drag_handle(bug_id));
var s = new Ext.dd.DragSource(el,
{ddGroup: "milestones_drag_group"});
s.source_id = bug_id;
s.onDragDrop = handle_bug_drop;
s.onDrag = function(e) {in_drag = 1;};
s.endDrag = function (e) {in_drag = 0;};

I also tried using the onMouseUp() method of DragDrop.

Any help will be appreciated.

Animal
8 Aug 2009, 11:49 PM
Add a click listener, and call stopEvent on the event.

yyogev
8 Aug 2009, 11:58 PM
Add a click listener, and call stopEvent on the event.

Hello Animal,

Thanks for the quick reply.

Wouldn't stopEvent for onClick prevent navigation by clicking on the link altogether ?
I still want to allow the user to use the link by clicking.

Thanks,

Animal
9 Aug 2009, 4:30 AM
You only stop the event when the click is fire because of a drag. You must set a flag which is later cleared.

yyogev
12 Aug 2009, 2:09 AM
Hello again,

Keeping a flag turned out not to work, because the click event happens after endDrag is called.

Instead of this, I keep the date when the last drag ended, and if the click happens too soon after it - call stopEvent(). This works fine.

Here's the relevant code:


var last_drag_end;

// in render function
var bug_link = "<A href='/bugs/show_bug.cgi?id=" + value + "' " +
"id='bug_link_" + value +"' " +
">" + text +
"</A>";

// the click handling function

// if click on link came just after drag, abort link navigation
// "just after" means 0.2 second, which is about the shortest time in which a
// normal person can respond to an event
function handle_bug_link_click(e, p2, p3, p4, p5)
{
var t = new Date();
if (typeof last_drag_end == "undefined")
return;
if (t.getTime() - last_drag_end.getTime() > 1)
return; // more than 1 second difference
// check difference in milliseconds
var l = last_drag_end.getMilliseconds() +
1000 * last_drag_end.getSeconds();
var c = t.getMilliseconds() + 1000 * t.getSeconds();
if (c <= l+200)
e.stopEvent();
}

// the code that creates the drag element keeps the last drag time on endDrag
// and defines the event handler for the link click event
function set_issue_as_draggable(el, bug_id)
{
var s = new Ext.dd.DragSource(el,
{ddGroup: "issues_drag_group"});
s.onDragDrop = handle_bug_drop;
s.endDrag = function (e) {last_drag_end = new Date();};
bug_link_el = Ext.get("bug_link_" + bug_id);
bug_link_el.on("click", handle_bug_link_click);
}

Thanks,