YUI Library Home

YUI Library Examples: Drag & Drop: Custom Click Validator

Drag & Drop: Custom Click Validator

This example demonstrates how to implement a custom click validator to make a circular drag and drop implementation. Because all DOM elements that have dimensions are rectangular, the way to implement a circular drag object is to perform calculations on mousedown to determine whether the mouse was targeting a valid portion of the element (eg, a portion within the circle).

The same method could be used to create any non-rectangular draggable object.


DD
DDTarget

Basic Drag and Drop

The Drag & Drop Utility lets you make HTML elements draggable.

For this example, we will enable drag and drop for the three <div> elements.

Markup:

1<div id="dd-demo-1" class="dd-demo"><br />DD</div> 
2<div id="dd-demo-2" class="dd-demo">DDTarget</div> 
view plain | print | ?

Code:

1<script type="text/javascript"
2    (function() { 
3 
4        var dd, dd2, clickRadius = 46, startPos, 
5            Event=YAHOO.util.Event, Dom=YAHOO.util.Dom; 
6 
7        YAHOO.util.Event.onDOMReady(function() { 
8 
9            var el = Dom.get("dd-demo-1"); 
10            startPos = Dom.getXY(el); 
11 
12            dd = new YAHOO.util.DD(el); 
13 
14            // our custom click validator let's us prevent clicks outside 
15            // of the circle (but within the element) from initiating a 
16            // drag. 
17            dd.clickValidator = function(e) { 
18 
19                // get the screen rectangle for the element 
20                var el = this.getEl(); 
21                var region = Dom.getRegion(el); 
22 
23                // get the radius of the largest circle that can fit inside 
24                // var w = region.right - region.left; 
25                // var h = region.bottom - region.top; 
26                // var r = Math.round(Math.min(h, w) / 2); 
27                //-or- just use a well-known radius 
28                var r = clickRadius; 
29 
30                // get the location of the click 
31                var x1 = Event.getPageX(e), y1 = Event.getPageY(e); 
32 
33                // get the center of the circle 
34                var x2 = Math.round((region.right+region.left)/2); 
35                var y2 = Math.round((region.top+region.bottom)/2); 
36 
37 
38                // I don't want text selection even if the click does not 
39                // initiate a drag 
40                Event.preventDefault(e); 
41 
42                // check to see if the click is in the circle 
43                return ( ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)) <= r*r ); 
44            }; 
45 
46            dd.onDragDrop = function(e, id) { 
47                // center it in the square 
48                Dom.setXY(this.getEl(), Dom.getXY(id)); 
49            } 
50 
51            dd.onInvalidDrop = function(e) { 
52                // return to the start position 
53                // Dom.setXY(this.getEl(), startPos); 
54 
55                // Animating the move is more intesting 
56                new YAHOO.util.Motion( 
57                    this.id, { 
58                        points: { 
59                            to: startPos 
60                        } 
61                    }, 
62                    0.3, 
63                    YAHOO.util.Easing.easeOut 
64                ).animate(); 
65 
66            } 
67 
68            dd2 = new YAHOO.util.DDTarget("dd-demo-2"); 
69 
70        }); 
71 
72    })(); 
73</script> 
view plain | print | ?

Configuration for This Example

You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.

YUI Logger Output:

Logger Console

INFO 444ms (+0) 6:33:21 PM:

DDTarget dd-demo-2

dd-demo-2 initial position: 188, 485

INFO 444ms (+1) 6:33:21 PM:

DD dd-demo-1

dd-demo-1 initial position: 8, 375

INFO 443ms (+18) 6:33:21 PM:

DD loggerDiv

loggerDiv initial position: 8, 2426

INFO 425ms (+22) 6:33:21 PM:

global

id is not a string, assuming it is an HTMLElement

INFO 403ms (+2) 6:33:21 PM:

global

id is not a string, assuming it is an HTMLElement

INFO 401ms (+1) 6:33:21 PM:

LogReader instance0

LogReader initialized

INFO 400ms (+1) 6:33:21 PM:

Get

Appending node: ../../../2.x/build/event-mouseenter/event-mouseenter-min.js

INFO 399ms (+0) 6:33:21 PM:

Get

attempting to load ../../../2.x/build/event-mouseenter/event-mouseenter-min.js

INFO 399ms (+38) 6:33:21 PM:

Get

_next: q0, loaded: undefined

INFO 361ms (+361) 6:33:21 PM:

DragDropMgr

DragDropMgr onload

INFO 0ms (+0) 6:33:20 PM:

global

Logger initialized

Note: You are viewing this example in debug mode with logging enabled. This can significantly slow performance.

Reload with logging
and debugging disabled.

More Drag & Drop Resources:

Copyright © 2011 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings