AutorÃa | Ultima modificación | Ver Log |
YUI.add('sortable', function (Y, NAME) {/*** The class allows you to create a Drag & Drop reordered list.* @module sortable*//*** The class allows you to create a Drag & Drop reordered list.* @class Sortable* @extends Base* @constructor*/var Sortable = function() {Sortable.superclass.constructor.apply(this, arguments);},CURRENT_NODE = 'currentNode',OPACITY_NODE = 'opacityNode',CONT = 'container',ID = 'id',ZINDEX = 'zIndex',OPACITY = 'opacity',PARENT_NODE = 'parentNode',NODES = 'nodes',NODE = 'node';Y.extend(Sortable, Y.Base, {/*** @property delegate* @type DD.Delegate* @description A reference to the DD.Delegate instance.*/delegate: null,/*** @property drop* @type DD.Drop* @description A reference to the DD.Drop instance*/drop: null,initializer: function() {var id = 'sortable-' + Y.guid(),delConfig = {container: this.get(CONT),nodes: this.get(NODES),target: true,invalid: this.get('invalid'),dragConfig: {groups: [ id ]}}, del;if (this.get('handles')) {delConfig.handles = this.get('handles');}del = new Y.DD.Delegate(delConfig);this.set(ID, id);del.dd.plug(Y.Plugin.DDProxy, {moveOnEnd: false,cloneNode: true});this.drop = new Y.DD.Drop({node: this.get(CONT),bubbleTarget: del,groups: del.dd.get('groups')});this.drop.on('drop:enter', Y.bind(this._onDropEnter, this));del.on({'drag:start': Y.bind(this._onDragStart, this),'drag:end': Y.bind(this._onDragEnd, this),'drag:over': Y.bind(this._onDragOver, this),'drag:drag': Y.bind(this._onDrag, this)});this.delegate = del;Sortable.reg(this, id);},_up: null,_y: null,_onDrag: function(e) {if (e.pageY < this._y) {this._up = true;} else if (e.pageY > this._y) {this._up = false;}this._y = e.pageY;},/*** @private* @method _onDropEnter* @param Event e The Event Object* @description Handles the DropEnter event to append a new node to a target.*/_onDropEnter: function(e) {var dropNode = e.drop.get(NODE),dragNode = e.drag.get(NODE);if (!dropNode.test(this.get(NODES)) &&!dragNode.get(PARENT_NODE).compareTo(dropNode)) {dropNode.append(dragNode);}},/*** @private* @method _onDragOver* @param Event e The Event Object* @description Handles the DragOver event that moves the object in the list or to another list.*/_onDragOver: function(e) {if (!e.drop.get(NODE).test(this.get(NODES))) {return;}if (e.drag.get(NODE) === e.drop.get(NODE)) {return;}// is drop a child of drag?if (e.drag.get(NODE).contains(e.drop.get(NODE))) {return;}var same = false, dir, oldNode, newNode, dropsort, dropNode,moveType = this.get('moveType').toLowerCase();if (e.drag.get(NODE).get(PARENT_NODE).contains(e.drop.get(NODE))) {same = true;}if (same && moveType === 'move') {moveType = 'insert';}switch (moveType) {case 'insert':dir = ((this._up) ? 'before' : 'after');dropNode = e.drop.get(NODE);if (Y.Sortable._test(dropNode, this.get(CONT))) {dropNode.append(e.drag.get(NODE));} else {dropNode.insert(e.drag.get(NODE), dir);}break;case 'swap':Y.DD.DDM.swapNode(e.drag, e.drop);break;case 'move':case 'copy':dropsort = Y.Sortable.getSortable(e.drop.get(NODE).get(PARENT_NODE));if (!dropsort) {return;}Y.DD.DDM.getDrop(e.drag.get(NODE)).addToGroup(dropsort.get(ID));//Same Listif (same) {Y.DD.DDM.swapNode(e.drag, e.drop);} else {if (this.get('moveType') === 'copy') {//New ListoldNode = e.drag.get(NODE);newNode = oldNode.cloneNode(true);newNode.set(ID, '');e.drag.set(NODE, newNode);dropsort.delegate.createDrop(newNode, [dropsort.get(ID)]);oldNode.setStyles({top: '',left: ''});}e.drop.get(NODE).insert(e.drag.get(NODE), 'before');}break;}this.fire(moveType, { same: same, drag: e.drag, drop: e.drop });this.fire('moved', { same: same, drag: e.drag, drop: e.drop });},/*** @private* @method _onDragStart* @param Event e The Event Object* @description Handles the DragStart event and initializes some settings.*/_onDragStart: function() {var del = this.delegate,lastNode = del.get('lastNode');if (lastNode && lastNode.getDOMNode()) {lastNode.setStyle(ZINDEX, '');}del.get(this.get(OPACITY_NODE)).setStyle(OPACITY, this.get(OPACITY));del.get(CURRENT_NODE).setStyle(ZINDEX, '999');},/*** @private* @method _onDragEnd* @param Event e The Event Object* @description Handles the DragEnd event that cleans up the settings in the drag:start event.*/_onDragEnd: function() {this.delegate.get(this.get(OPACITY_NODE)).setStyle(OPACITY, 1);this.delegate.get(CURRENT_NODE).setStyle(ZINDEX, '');this.delegate.get(CURRENT_NODE).setStyles({top: '',left: ''});this.sync();},/*** @method plug* @param Class cls The class to plug* @param Object config The class config* @description Passthrough to the DD.Delegate.ddplug method* @chainable*/plug: function(cls, config) {//I don't like this.. Not at all, need to discuss with the teamif (cls && cls.NAME.substring(0, 4).toLowerCase() === 'sort') {this.constructor.superclass.plug.call(this, cls, config);} else {this.delegate.dd.plug(cls, config);}return this;},/*** @method sync* @description Passthrough to the DD.Delegate syncTargets method.* @chainable*/sync: function() {this.delegate.syncTargets();return this;},destructor: function() {this.drop.destroy();this.delegate.destroy();Sortable.unreg(this, this.get(ID));},/*** @method join* @param Sortable sel The Sortable list to join with* @param String type The type of join to do: full, inner, outer, none. Default: full* @description Join this Sortable with another Sortable instance.* <ul>* <li>full: Exchange nodes with both lists.</li>* <li>inner: Items can go into this list from the joined list.</li>* <li>outer: Items can go out of the joined list into this list.</li>* <li>none: Removes the join.</li>* </ul>* @chainable*/join: function(sel, type) {if (!(sel instanceof Y.Sortable)) {Y.error('Sortable: join needs a Sortable Instance');return this;}if (!type) {type = 'full';}type = type.toLowerCase();var method = '_join_' + type;if (this[method]) {this[method](sel);}return this;},/*** @private* @method _join_none* @param Sortable sel The Sortable to remove the join from* @description Removes the join with the passed Sortable.*/_join_none: function(sel) {this.delegate.dd.removeFromGroup(sel.get(ID));sel.delegate.dd.removeFromGroup(this.get(ID));},/*** @private* @method _join_full* @param Sortable sel The Sortable list to join with* @description Joins both of the Sortables together.*/_join_full: function(sel) {this.delegate.dd.addToGroup(sel.get(ID));sel.delegate.dd.addToGroup(this.get(ID));},/*** @private* @method _join_outer* @param Sortable sel The Sortable list to join with* @description Allows this Sortable to accept items from the passed Sortable.*/_join_outer: function(sel) {this.delegate.dd.addToGroup(sel.get(ID));},/*** @private* @method _join_inner* @param Sortable sel The Sortable list to join with* @description Allows this Sortable to give items to the passed Sortable.*/_join_inner: function(sel) {sel.delegate.dd.addToGroup(this.get(ID));},/*** A custom callback to allow a user to extract some sort of id or any other data* from the node to use in the "ordering list" and then that data should be returned from the callback.* @method getOrdering* @param Function callback* @return Array*/getOrdering: function(callback) {var ordering = [];if (!Y.Lang.isFunction(callback)) {callback = function (node) {return node;};}Y.one(this.get(CONT)).all(this.get(NODES)).each(function(node) {ordering.push(callback(node));});return ordering;}}, {NAME: 'sortable',ATTRS: {/*** @attribute handles* @description Drag handles to pass on to the internal DD.Delegate instance.* @type Array*/handles: {value: false},/*** @attribute container* @description A selector query to get the container to listen for mousedown events on. All "nodes" should be a child of this container.* @type String*/container: {value: 'body'},/*** @attribute nodes* @description A selector query to get the children of the "container" to make draggable elements from.* @type String*/nodes: {value: '.dd-draggable'},/*** @attribute opacity* @description The opacity to change the proxy item to when dragging.* @type String*/opacity: {value: '.75'},/*** @attribute opacityNode* @description The node to set opacity on when dragging (dragNode or currentNode). Default: currentNode.* @type String*/opacityNode: {value: 'currentNode'},/*** @attribute id* @description The id of this Sortable, used to get a reference to this Sortable list from another list.* @type String*/id: {value: null},/*** @attribute moveType* @description How should an item move to another list: insert, swap, move, copy. Default: insert* @type String*/moveType: {value: 'insert'},/*** @attribute invalid* @description A selector string to test if a list item is invalid and not sortable* @type String*/invalid: {value: ''}},/*** @static* @property _sortables* @private* @type Object* @description Hash map of all Sortables on the page.*/_sortables: {},/*** @static* @method _test* @param {Node} node The node instance to test.* @param {String|Node} test The node instance or selector string to test against.* @description Test a Node or a selector for the container*/_test: function(node, test) {var ret;if (test instanceof Y.Node) {ret = (test === node);} else {ret = node.test(test);}return ret;},/*** @static* @method getSortable* @param {String|Node} node The node instance or selector string to use to find a Sortable instance.* @description Get a Sortable instance back from a node reference or a selector string.*/getSortable: function(node) {var s = null,id = null;node = Y.one(node);id = node.get(ID);if(id && Y.Sortable._sortables[id]) {return Y.Sortable._sortables[id];}Y.Object.each(Y.Sortable._sortables, function(v) {if (Y.Sortable._test(node, v.get(CONT))) {s = v;}});return s;},/*** @static* @method reg* @param Sortable s A Sortable instance.* @param String id (optional) The id of the sortable instance.* @description Register a Sortable instance with the singleton to allow lookups later.*/reg: function(s, id) {if (!id) {id = s.get(ID);}Y.Sortable._sortables[id] = s;},/*** @static* @method unreg* @param Sortable s A Sortable instance.* @param String id (optional) The id of the sortable instance.* @description Unregister a Sortable instance with the singleton.*/unreg: function(s, id) {if (!id) {id = s.get(ID);}if (id && Y.Sortable._sortables[id]) {delete Y.Sortable._sortables[id];return;}Y.Object.each(Y.Sortable._sortables, function(v, k) {if (v === s) {delete Sortable._sortables[k];}});}});Y.Sortable = Sortable;/*** @event copy* @description A Sortable node was moved with a copy.* @param {EventFacade} event An Event Facade object* @param {Boolean} event.same Moved to the same list.* @param {DD.Drag} event.drag The drag instance.* @param {DD.Drop} event.drop The drop instance.*//*** @event move* @description A Sortable node was moved with a move.* @param {EventFacade} event An Event Facade object with the following specific property added:* @param {Boolean} event.same Moved to the same list.* @param {DD.Drag} event.drag The drag instance.* @param {DD.Drop} event.drop The drop instance.*//*** @event insert* @description A Sortable node was moved with an insert.* @param {EventFacade} event An Event Facade object with the following specific property added:* @param {Boolean} event.same Moved to the same list.* @param {DD.Drag} event.drag The drag instance.* @param {DD.Drop} event.drop The drop instance.*//*** @event swap* @description A Sortable node was moved with a swap.* @param {EventFacade} event An Event Facade object with the following specific property added:* @param {Boolean} event.same Moved to the same list.* @param {DD.Drag} event.drag The drag instance.* @param {DD.Drop} event.drop The drop instance.*//*** @event moved* @description A Sortable node was moved.* @param {EventFacade} event An Event Facade object with the following specific property added:* @param {Boolean} event.same Moved to the same list.* @param {DD.Drag} event.drag The drag instance.* @param {DD.Drop} event.drop The drop instance.*/}, '3.18.1', {"requires": ["dd-delegate", "dd-drop-plugin", "dd-proxy"]});