// A DropZone which cooperates with DragZones whose dragData contains // a "field" property representing a form Field. Fields may be dropped onto // grid data cells containing a matching data type. Ext.define('Ext.ux.dd.CellFieldDropZone', { extend: 'Ext.dd.DropZone', constructor: function(cfg){ cfg = cfg || {}; if (cfg.onCellDrop) { this.onCellDrop = cfg.onCellDrop; } if (cfg.ddGroup) { this.ddGroup = cfg.ddGroup; } }, // Call the DropZone constructor using the View's scrolling element // only after the grid has been rendered. init: function(grid) { var me = this; if (grid.rendered) { me.grid = grid; grid.getView().on({ render: function(v) { me.view = v; Ext.ux.dd.CellFieldDropZone.superclass.constructor.call(me, me.view.el); }, single: true }); } else { grid.on('render', me.init, me, {single: true}); } }, // Scroll the main configured Element when we drag close to the edge containerScroll: true, getTargetFromEvent: function(e) { var me = this, v = me.view; // Ascertain whether the mousemove is within a grid cell var cell = e.getTarget(v.getCellSelector()); if (cell) { // We *are* within a grid cell, so ask the View exactly which one, // Extract data from the Model to create a target object for // processing in subsequent onNodeXXXX methods. Note that the target does // not have to be a DOM element. It can be whatever the noNodeXXX methods are // programmed to expect. var row = v.findItemByChild(cell), columnIndex = cell.cellIndex; if (row && Ext.isDefined(columnIndex)) { return { node: cell, record: v.getRecord(row), fieldName: me.grid.getVisibleColumnManager().getColumns()[columnIndex].dataIndex }; } } }, // On Node enter, see if it is valid for us to drop the field on that type of column. onNodeEnter: function(target, dd, e, dragData) { delete this.dropOK; if (!target) { return; } // Check that a field is being dragged. var f = dragData.field; if (!f) { return; } // Check whether the data type of the column being dropped on accepts the // dragged field type. If so, set dropOK flag, and highlight the target node. var field = target.record.fieldsMap[target.fieldName]; if (field.isNumeric) { if (!f.isXType('numberfield')) { return; } } else if (field.isDateField) { if (!f.isXType('datefield')) { return; } } else if (field.isBooleanField) { if (!f.isXType('checkbox')) { return; } } this.dropOK = true; Ext.fly(target.node).addCls('x-drop-target-active'); }, // Return the class name to add to the drag proxy. This provides a visual indication // of drop allowed or not allowed. onNodeOver: function(target, dd, e, dragData) { return this.dropOK ? this.dropAllowed : this.dropNotAllowed; }, // highlight the target node. onNodeOut: function(target, dd, e, dragData) { Ext.fly(target.node).removeCls('x-drop-target-active'); }, // Process the drop event if we have previously ascertained that a drop is OK. onNodeDrop: function(target, dd, e, dragData) { if (this.dropOK) { var value = dragData.field.getValue(); target.record.set(target.fieldName, value); this.onCellDrop(target.fieldName, value); return true; } }, onCellDrop: Ext.emptyFn});