X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/examples/ux/DataView/Draggable.js diff --git a/examples/ux/DataView/Draggable.js b/examples/ux/DataView/Draggable.js new file mode 100644 index 00000000..d35b0388 --- /dev/null +++ b/examples/ux/DataView/Draggable.js @@ -0,0 +1,203 @@ +/** + * @class Ext.ux.DataView.Draggable + * @extends Object + * @author Ed Spencer + * +

+Ext.create('Ext.view.View', {
+    mixins: {
+        draggable: 'Ext.ux.DataView.Draggable'
+    },
+
+    initComponent: function() {
+        this.mixins.draggable.init(this, {
+            ddConfig: {
+                ddGroup: 'someGroup'
+            }
+        });
+
+        this.callParent(arguments);
+    }
+});
+
+ * + */ +Ext.define('Ext.ux.DataView.Draggable', { + requires: 'Ext.dd.DragZone', + + /** + * @cfg {String} ghostCls The CSS class added to the outermost element of the created ghost proxy + * (defaults to 'x-dataview-draggable-ghost') + */ + ghostCls: 'x-dataview-draggable-ghost', + + /** + * @cfg {Ext.XTemplate/Array} ghostTpl The template used in the ghost DataView + */ + ghostTpl: [ + '', + '{title}', + '' + ], + + /** + * @cfg {Object} ddConfig Config object that is applied to the internally created DragZone + */ + + /** + * @cfg {String} ghostConfig Config object that is used to configure the internally created DataView + */ + + init: function(dataview, config) { + /** + * @property dataview + * @type Ext.view.View + * The Ext.view.View instance that this DragZone is attached to + */ + this.dataview = dataview; + + dataview.on('render', this.onRender, this); + + Ext.apply(this, { + itemSelector: dataview.itemSelector, + ghostConfig : {} + }, config || {}); + + Ext.applyIf(this.ghostConfig, { + itemSelector: 'img', + cls: this.ghostCls, + tpl: this.ghostTpl + }); + }, + + /** + * @private + * Called when the attached DataView is rendered. Sets up the internal DragZone + */ + onRender: function() { + var config = Ext.apply({}, this.ddConfig || {}, { + dvDraggable: this, + dataview : this.dataview, + getDragData: this.getDragData, + getTreeNode: this.getTreeNode, + afterRepair: this.afterRepair, + getRepairXY: this.getRepairXY + }); + + /** + * @property dragZone + * @type Ext.dd.DragZone + * The attached DragZone instane + */ + this.dragZone = Ext.create('Ext.dd.DragZone', this.dataview.getEl(), config); + }, + + getDragData: function(e) { + var draggable = this.dvDraggable, + dataview = this.dataview, + selModel = dataview.getSelectionModel(), + target = e.getTarget(draggable.itemSelector), + selected, dragData; + + if (target) { + if (!dataview.isSelected(target)) { + selModel.select(dataview.getRecord(target)); + } + + selected = dataview.getSelectedNodes(); + dragData = { + copy: true, + nodes: selected, + records: selModel.getSelection(), + item: true + }; + + if (selected.length == 1) { + dragData.single = true; + dragData.ddel = target; + } else { + dragData.multi = true; + dragData.ddel = draggable.prepareGhost(selModel.getSelection()).dom; + } + + return dragData; + } + + return false; + }, + + getTreeNode: function() { + console.log('test'); + }, + + afterRepair: function() { + this.dragging = false; + + var nodes = this.dragData.nodes, + length = nodes.length, + i; + + //FIXME: Ext.fly does not work here for some reason, only frames the last node + for (i = 0; i < length; i++) { + Ext.get(nodes[i]).frame('#8db2e3', 1); + } + }, + + /** + * @private + * Returns the x and y co-ordinates that the dragged item should be animated back to if it was dropped on an + * invalid drop target. If we're dragging more than one item we don't animate back and just allow afterRepair + * to frame each dropped item. + */ + getRepairXY: function(e) { + if (this.dragData.multi) { + return false; + } else { + var repairEl = Ext.get(this.dragData.ddel), + repairXY = repairEl.getXY(); + + //take the item's margins and padding into account to make the repair animation line up perfectly + repairXY[0] += repairEl.getPadding('t') + repairEl.getMargin('t'); + repairXY[1] += repairEl.getPadding('l') + repairEl.getMargin('l'); + + return repairXY; + } + }, + + /** + * Updates the internal ghost DataView by ensuring it is rendered and contains the correct records + * @param {Array} records The set of records that is currently selected in the parent DataView + * @return {Ext.view.View} The Ghost DataView + */ + prepareGhost: function(records) { + var ghost = this.createGhost(records), + store = ghost.store; + + store.removeAll(); + store.add(records); + + return ghost.getEl(); + }, + + /** + * @private + * Creates the 'ghost' DataView that follows the mouse cursor during the drag operation. This div is usually a + * lighter-weight representation of just the nodes that are selected in the parent DataView. Delegates the creation + * of each selected item's element to {@link createGhostElement} + */ + createGhost: function(records) { + if (!this.ghost) { + var ghostConfig = Ext.apply({}, this.ghostConfig, { + store: Ext.create('Ext.data.Store', { + model: records[0].modelName + }) + }); + + this.ghost = Ext.create('Ext.view.View', ghostConfig); + + this.ghost.render(document.createElement('div')); + } + + return this.ghost; + } +});