]>
git.proxmox.com Git - extjs.git/blob - extjs/modern/modern/src/Sortable.js
2 * A mixin which allows a data component to be sorted
5 Ext
.define('Ext.Sortable', {
7 observable
: 'Ext.mixin.Observable'
10 requires
: ['Ext.util.Draggable'],
17 baseCls
: Ext
.baseCSSPrefix
+ 'sortable',
21 * How many milliseconds a user must hold the draggable before starting a
31 * @cfg {String} direction
32 * Possible values: 'vertical', 'horizontal'.
34 direction
: 'vertical',
37 * @cfg {String} cancelSelector
38 * A simple CSS selector that represents elements within the draggable
39 * that should NOT initiate a drag.
43 // not yet implemented
49 * @cfg {HTMLElement/Boolean} constrain
50 * An Element to constrain the Sortable dragging to.
51 * If `true` is specified, the dragging will be constrained to the element
57 * Draggable and Droppable objects can participate in a group which are
58 * capable of interacting.
63 * @cfg {Boolean} revert
64 * This should NOT be changed.
70 * @cfg {String} itemSelector
71 * A simple CSS selector that represents individual items within the Sortable.
76 * @cfg {String} handleSelector
77 * A simple CSS selector to indicate what is the handle to drag the Sortable.
82 * @cfg {Boolean} disabled
83 * Passing in `true` will disable this Sortable.
90 * Read-only property that indicates whether a Sortable is currently sorting.
98 * Read-only value representing whether the Draggable can be moved vertically.
99 * This is automatically calculated by Draggable by the direction configuration.
107 * Creates new Sortable.
109 * @param {Object} config
111 constructor : function(el
, config
) {
112 config
= config
|| {};
113 Ext
.apply(this, config
);
118 * @param {Ext.Sortable} this
119 * @param {Ext.event.Event} e
124 * @param {Ext.Sortable} this
125 * @param {Ext.event.Event} e
130 * @param {Ext.Sortable} this
131 * @param {Ext.Element} el The Element being dragged.
132 * @param {Number} index The index of the element after the sort change.
136 // not yet implemented.
146 this.el
= Ext
.get(el
);
149 this.mixins
.observable
.constructor.call(this);
151 if (this.direction
== 'horizontal') {
152 this.horizontal
= true;
154 else if (this.direction
== 'vertical') {
155 this.vertical
= true;
158 this.horizontal
= this.vertical
= true;
161 this.el
.addCls(this.baseCls
);
162 this.startEventName
= (this.getDelay() > 0) ? 'taphold' : 'tapstart';
163 if (!this.disabled
) {
171 onStart : function(e
, t
) {
172 if (this.cancelSelector
&& e
.getTarget(this.cancelSelector
)) {
175 if (this.handleSelector
&& !e
.getTarget(this.handleSelector
)) {
180 this.onSortStart(e
, t
);
187 onSortStart : function(e
, t
) {
189 var draggable
= Ext
.create('Ext.util.Draggable', t
, {
192 direction
: this.direction
,
193 constrain
: this.constrain
=== true ? this.el
: this.constrain
,
194 animationDuration
: 100
198 dragend
: this.onDragEnd
,
203 this.calculateBoxes();
205 if (!draggable
.dragging
) {
206 draggable
.onStart(e
);
209 this.fireEvent('sortstart', this, e
);
215 calculateBoxes : function() {
217 var els
= this.el
.select(this.itemSelector
, false),
218 ln
= els
.length
, i
, item
, el
, box
;
220 for (i
= 0; i
< ln
; i
++) {
222 if (el
!= this.dragEl
) {
223 item
= Ext
.fly(el
).getRegion();
225 this.items
.push(item
);
233 onDrag : function(draggable
, e
) {
234 var items
= this.items
,
236 region
= draggable
.region
,
238 i
, intersect
, overlap
, item
;
240 for (i
= 0; i
< ln
; i
++) {
242 intersect
= region
.intersect(item
);
244 if (this.vertical
&& Math
.abs(intersect
.top
- intersect
.bottom
) > (region
.bottom
- region
.top
) / 2) {
245 if (region
.bottom
> item
.top
&& item
.top
> region
.top
) {
246 draggable
.el
.insertAfter(item
.el
);
249 draggable
.el
.insertBefore(item
.el
);
253 else if (this.horizontal
&& Math
.abs(intersect
.left
- intersect
.right
) > (region
.right
- region
.left
) / 2) {
254 if (region
.right
> item
.left
&& item
.left
> region
.left
) {
255 draggable
.el
.insertAfter(item
.el
);
258 draggable
.el
.insertBefore(item
.el
);
264 // We reset the draggable (initializes all the new start values)
267 // Move the draggable to its current location (since the transform is now
269 draggable
.moveTo(region
.left
, region
.top
);
271 // Finally lets recalculate all the items boxes
272 this.calculateBoxes();
273 this.fireEvent('sortchange', this, draggable
.el
, this.el
.select(this.itemSelector
, false).indexOf(draggable
.el
.dom
));
283 onDragEnd : function(draggable
, e
) {
285 this.sorting
= false;
286 this.fireEvent('sortend', this, draggable
, e
);
290 * Enables sorting for this Sortable.
291 * This method is invoked immediately after construction of a Sortable unless
292 * the disabled configuration is set to `true`.
294 enable : function() {
295 this.el
.on(this.startEventName
, this.onStart
, this, {delegate
: this.itemSelector
, holdThreshold
: this.getDelay()});
296 this.disabled
= false;
300 * Disables sorting for this Sortable.
302 disable : function() {
303 this.el
.un(this.startEventName
, this.onStart
, this);
304 this.disabled
= true;
308 * Method to determine whether this Sortable is currently disabled.
309 * @return {Boolean} The disabled state of this Sortable.
311 isDisabled: function() {
312 return this.disabled
;
316 * Method to determine whether this Sortable is currently sorting.
317 * @return {Boolean} The sorting state of this Sortable.
319 isSorting : function() {
324 * Method to determine whether this Sortable is currently disabled.
325 * @return {Boolean} The disabled state of this Sortable.
327 isVertical : function() {
328 return this.vertical
;
332 * Method to determine whether this Sortable is currently sorting.
333 * @return {Boolean} The sorting state of this Sortable.
335 isHorizontal : function() {
336 return this.horizontal
;