2 * @class Ext.ux.DataView.DragSelector
7 Ext.define('Ext.ux.DataView.DragSelector', {
8 requires: ['Ext.dd.DragTracker', 'Ext.util.Region'],
11 * Initializes the plugin by setting up the drag tracker
13 init: function(dataview) {
17 * The DataView bound to this instance
19 this.dataview = dataview;
20 dataview.mon(dataview, {
21 beforecontainerclick: this.cancelClick,
33 * Called when the attached DataView is rendered. This sets up the DragTracker instance that will be used
34 * to created a dragged selection area
36 onRender: function() {
39 * @type Ext.dd.DragTracker
40 * The DragTracker attached to this instance. Note that the 4 on* functions are called in the scope of the
41 * DragTracker ('this' refers to the DragTracker inside those functions), so we pass a reference to the
42 * DragSelector so that we can call this class's functions.
44 this.tracker = Ext.create('Ext.dd.DragTracker', {
45 dataview: this.dataview,
48 onBeforeStart: this.onBeforeStart,
49 onStart: this.onStart,
55 * @property dragRegion
56 * @type Ext.util.Region
57 * Represents the region currently dragged out by the user. This is used to figure out which dataview nodes are
58 * in the selected area and to set the size of the Proxy element used to highlight the current drag area
60 this.dragRegion = Ext.create('Ext.util.Region');
65 * Listener attached to the DragTracker's onBeforeStart event. Returns false if the drag didn't start within the
68 onBeforeStart: function(e) {
69 return e.target == this.dataview.getEl().dom;
74 * Listener attached to the DragTracker's onStart event. Cancel's the DataView's containerclick event from firing
75 * and sets the start co-ordinates of the Proxy element. Clears any existing DataView selection
76 * @param {EventObject} e The click event
78 onStart: function(e) {
79 var dragSelector = this.dragSelector,
80 dataview = this.dataview;
82 // Flag which controls whether the cancelClick method vetoes the processing of the DataView's containerclick event.
83 // On IE (where else), this needs to remain set for a millisecond after mouseup because even though the mouse has
84 // moved, the mouseup will still trigger a click event.
87 //here we reset and show the selection proxy element and cache the regions each item in the dataview take up
88 dragSelector.fillRegions();
89 dragSelector.getProxy().show();
90 dataview.getSelectionModel().deselectAll();
95 * Reusable handler that's used to cancel the container click event when dragging on the dataview. See onStart for
98 cancelClick: function() {
99 return !this.tracker.dragging;
104 * Listener attached to the DragTracker's onDrag event. Figures out how large the drag selection area should be and
105 * updates the proxy element's size to match. Then iterates over all of the rendered items and marks them selected
106 * if the drag region touches them
107 * @param {EventObject} e The drag event
109 onDrag: function(e) {
110 var dragSelector = this.dragSelector,
111 selModel = dragSelector.dataview.getSelectionModel(),
112 dragRegion = dragSelector.dragRegion,
113 bodyRegion = dragSelector.bodyRegion,
114 proxy = dragSelector.getProxy(),
115 regions = dragSelector.regions,
116 length = regions.length,
118 startXY = this.startXY,
119 currentXY = this.getXY(),
120 minX = Math.min(startXY[0], currentXY[0]),
121 minY = Math.min(startXY[1], currentXY[1]),
122 width = Math.abs(startXY[0] - currentXY[0]),
123 height = Math.abs(startXY[1] - currentXY[1]),
126 Ext.apply(dragRegion, {
130 bottom: minY + height
133 dragRegion.constrainTo(bodyRegion);
134 proxy.setRegion(dragRegion);
136 for (i = 0; i < length; i++) {
138 selected = dragRegion.intersect(region);
141 selModel.select(i, true);
143 selModel.deselect(i);
150 * Listener attached to the DragTracker's onEnd event. This is a delayed function which executes 1
151 * millisecond after it has been called. This is because the dragging flag must remain active to cancel
152 * the containerclick event which the mouseup event will trigger.
153 * @param {EventObject} e The event object
155 onEnd: Ext.Function.createDelayed(function(e) {
156 var dataview = this.dataview,
157 selModel = dataview.getSelectionModel(),
158 dragSelector = this.dragSelector;
160 this.dragging = false;
161 dragSelector.getProxy().hide();
166 * Creates a Proxy element that will be used to highlight the drag selection region
167 * @return {Ext.Element} The Proxy element
169 getProxy: function() {
171 this.proxy = this.dataview.getEl().createChild({
173 cls: 'x-view-selector'
181 * Gets the region taken up by each rendered node in the DataView. We use these regions to figure out which nodes
182 * to select based on the selector region the user has dragged out
184 fillRegions: function() {
185 var dataview = this.dataview,
186 regions = this.regions = [];
188 dataview.all.each(function(node) {
189 regions.push(node.getRegion());
191 this.bodyRegion = dataview.getEl().getRegion();