2
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3
Code licensed under the BSD License:
4
http://developer.yahoo.com/yui/license.html
8
YUI.add('sortable', function(Y) {
12
* The class allows you to create a Drag & Drop reordered list.
16
* The class allows you to create a Drag & Drop reordered list.
23
var Sortable = function(o) {
24
Sortable.superclass.constructor.apply(this, arguments);
26
CURRENT_NODE = 'currentNode',
27
OPACITY_NODE = 'opacityNode',
32
PARENT_NODE = 'parentNode',
37
Y.extend(Sortable, Y.Base, {
41
* @description A reference to the DD.Delegate instance.
44
initializer: function() {
45
var id = 'sortable-' + Y.guid(), c,
47
container: this.get(CONT),
48
nodes: this.get(NODES),
50
invalid: this.get('invalid'),
56
if (this.get('handles')) {
57
delConfig.handles = this.get('handles');
59
del = new Y.DD.Delegate(delConfig);
63
del.dd.plug(Y.Plugin.DDProxy, {
71
groups: del.dd.get('groups')
72
}).on('drop:over', Y.bind(this._onDropOver, this));
75
'drag:start': Y.bind(this._onDragStart, this),
76
'drag:end': Y.bind(this._onDragEnd, this),
77
'drag:over': Y.bind(this._onDragOver, this),
78
'drag:drag': Y.bind(this._onDrag, this)
86
_onDrag: function(e) {
87
if (e.pageY < this._y) {
89
} else if (e.pageY > this._y) {
98
* @param Event e The Event Object
99
* @description Handles the DropOver event to append a drop node to an empty target
101
_onDropOver: function(e) {
102
if (!e.drop.get(NODE).test(this.get(NODES))) {
103
var nodes = e.drop.get(NODE).all(this.get(NODES));
104
if (nodes.size() === 0) {
105
e.drop.get(NODE).append(e.drag.get(NODE));
111
* @method _onDragOver
112
* @param Event e The Event Object
113
* @description Handles the DragOver event that moves the object in the list or to another list.
115
_onDragOver: function(e) {
116
if (!e.drop.get(NODE).test(this.get(NODES))) {
119
if (e.drag.get(NODE) == e.drop.get(NODE)) {
123
switch (this.get('moveType').toLowerCase()) {
125
var dir = ((this._up) ? 'before' : 'after');
126
e.drop.get(NODE).insert(e.drag.get(NODE), dir);
129
Y.DD.DDM.swapNode(e.drag, e.drop);
133
var dropsort = Y.Sortable.getSortable(e.drop.get(NODE).get(PARENT_NODE)),
140
Y.DD.DDM.getDrop(e.drag.get(NODE)).addToGroup(dropsort.get(ID));
143
if (e.drag.get(NODE).get(PARENT_NODE).contains(e.drop.get(NODE))) {
144
Y.DD.DDM.swapNode(e.drag, e.drop);
146
if (this.get('moveType') == 'copy') {
148
oldNode = e.drag.get(NODE);
149
newNode = oldNode.cloneNode(true);
152
e.drag.set(NODE, newNode);
153
dropsort.delegate.createDrop(newNode, [dropsort.get(ID)]);
159
e.drop.get(NODE).insert(e.drag.get(NODE), 'before');
166
* @method _onDragStart
167
* @param Event e The Event Object
168
* @description Handles the DragStart event and initializes some settings.
170
_onDragStart: function(e) {
171
this.delegate.get('lastNode').setStyle(ZINDEX, '');
172
this.delegate.get(this.get(OPACITY_NODE)).setStyle(OPACITY, this.get(OPACITY));
173
this.delegate.get(CURRENT_NODE).setStyle(ZINDEX, '999');
178
* @param Event e The Event Object
179
* @description Handles the DragEnd event that cleans up the settings in the drag:start event.
181
_onDragEnd: function(e) {
182
this.delegate.get(this.get(OPACITY_NODE)).setStyle(OPACITY, 1);
183
this.delegate.get(CURRENT_NODE).setStyles({
191
* @param Class cls The class to plug
192
* @param Object config The class config
193
* @description Passthrough to the DD.Delegate.ddplug method
196
plug: function(cls, config) {
197
this.delegate.dd.plug(cls, config);
202
* @description Passthrough to the DD.Delegate syncTargets method.
206
this.delegate.syncTargets();
209
destructor: function() {
210
this.delegate.destroy();
211
Sortable.unreg(this);
215
* @param Sortable sel The sortable list to join with
216
* @param String type The type of join to do: full, inner, outer, none. Default: full
217
* @description Join this Sortable with another Sortable instance.
219
* <li>full: Exchange nodes with both lists.</li>
220
* <li>inner: Items can go into this list from the joined list.</li>
221
* <li>outer: Items can go out of the joined list into this list.</li>
222
* <li>none: Removes the join.</li>
226
join: function(sel, type) {
227
if (!(sel instanceof Y.Sortable)) {
228
Y.error('Sortable: join needs a Sortable Instance');
234
type = type.toLowerCase();
235
var method = '_join_' + type;
246
* @param Sortable sel The Sortable to remove the join from
247
* @description Removes the join with the passed Sortable.
249
_join_none: function(sel) {
250
this.delegate.dd.removeFromGroup(sel.get(ID));
251
sel.delegate.dd.removeFromGroup(this.get(ID));
256
* @param Sortable sel The sortable list to join with
257
* @description Joins both of the Sortables together.
259
_join_full: function(sel) {
260
this.delegate.dd.addToGroup(sel.get(ID));
261
sel.delegate.dd.addToGroup(this.get(ID));
265
* @method _join_outer
266
* @param Sortable sel The sortable list to join with
267
* @description Allows this Sortable to accept items from the passed Sortable.
269
_join_outer: function(sel) {
270
this.delegate.dd.addToGroup(sel.get(ID));
274
* @method _join_inner
275
* @param Sortable sel The sortable list to join with
276
* @description Allows this Sortable to give items to the passed Sortable.
278
_join_inner: function(sel) {
279
sel.delegate.dd.addToGroup(this.get(ID));
286
* @description Drag handles to pass on to the internal DD.Delegate instance.
293
* @attribute container
294
* @description A selector query to get the container to listen for mousedown events on. All "nodes" should be a child of this container.
302
* @description A selector query to get the children of the "container" to make draggable elements from.
306
value: '.dd-draggable'
310
* @description The ocpacity to test the proxy item to when dragging.
317
* @attribute opacityNode
318
* @description The node to set opacity on when dragging (dragNode or currentNode). Default: currentNode.
326
* @description The id of this sortable, used to get a reference to this sortable list from another list.
333
* @attribute moveType
334
* @description How should an item move to another list: insert, swap, move, copy. Default: insert
342
* @description A selector string to test if a list item is invalid and not sortable
351
* @property _sortables
354
* @description Hash map of all Sortables on the page.
359
* @method getSortable
360
* @param {String|Node} node The node instance or selector string to use to find a Sortable instance.
361
* @description Get a sortable instance back from a node reference or a selector string.
363
getSortable: function(node) {
366
Y.each(Sortable._sortables, function(v) {
367
if (node.test(v.get(CONT))) {
376
* @param Sortable s A Sortable instance.
377
* @description Register a Sortable instance with the singleton to allow lookups later.
380
Sortable._sortables.push(s);
385
* @param Sortable s A Sortable instance.
386
* @description Unregister a Sortable instance with the singleton.
389
Y.each(Sortable._sortables, function(v, k) {
391
Sortable._sortables[k] = null;
392
delete Sortable._sortables[k];
398
Y.Sortable = Sortable;
402
}, '3.1.0' ,{requires:['dd-delegate', 'dd-drop-plugin', 'dd-proxy']});