You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
5.6 KiB
JavaScript
203 lines
5.6 KiB
JavaScript
3 years ago
|
/**
|
||
|
* @class Ext.ux.DataView.Draggable
|
||
|
* @extends Object
|
||
|
* @author Ed Spencer
|
||
|
*
|
||
|
<pre><code>
|
||
|
Ext.create('Ext.view.View', {
|
||
|
mixins: {
|
||
|
draggable: 'Ext.ux.DataView.Draggable'
|
||
|
},
|
||
|
|
||
|
initComponent: function() {
|
||
|
this.mixins.draggable.init(this, {
|
||
|
ddConfig: {
|
||
|
ddGroup: 'someGroup'
|
||
|
}
|
||
|
});
|
||
|
|
||
|
this.callParent(arguments);
|
||
|
}
|
||
|
});
|
||
|
</code></pre>
|
||
|
*
|
||
|
*/
|
||
|
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: [
|
||
|
'<tpl for=".">',
|
||
|
'{title}',
|
||
|
'</tpl>'
|
||
|
],
|
||
|
|
||
|
/**
|
||
|
* @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.
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
});
|