Hi Shea,
I made some updates to make DataDrop a bit more configurable. I had a requirement where, say I dragged a 2 column spreadsheet onto the grid, but it was to be pasted in my GridPanel's columns 1 and 5.
I added an *optional* dataDropPluginCfg property obj for this, which accepts addBulk, highlightNewRows, and an xlsColMapper:
Usage (grid config snippet):
Code:
colModel: new Ext.grid.ColumnModel([
{header:" ", width:35, dataIndex:'rowNum', sortable:false, renderer:this.rowNumRenderer}
,{header:"User", dataIndex:'userId', sortable:false, editor:new Ext.form.TextField()}
,{header:"Age", dataIndex:'age', sortable:false, editor:new Ext.form.NumberField({allowNegative:false,allowDecimals:false})}
])
,dataDropPluginCfg:{addBulk:true, highlightNewRows:true, xlsColMapper:["userId","age"]}
,plugins: [Ext.ux.grid.DataDrop]
DataDrop.js
Code:
Ext.ns('Ext.ux.grid');
/**
* @author Shea Frederick - http://www.vinylfox.com
* @contributor Nigel (Animal) White, Andrea Giammarchi & Florian Cargoet
* @class Ext.ux.grid.DataDrop
* @singleton
* <p>A plugin that allows data to be dragged into a grid from spreadsheet applications (tabular data).</p>
* <p>Requires the Override.js file which adds mouse event forwarding capability to ExtJS</p>
* <p>Sample Usage</p>
* <pre><code>
{
xtype: 'grid',
...,
plugins: [Ext.ux.grid.DataDrop],
...
}
* </code></pre>
*/
Ext.ux.grid.DataDrop = (function(){
var lineEndRE = /\r\n|\r|\n/,
sepRe = /\s*\t\s*/;
// After the GridView has been rendered, insert a static transparent textarea over it.
function onViewRender(){
var v = this.view;
if (v.mainBody) {
this.textEl = Ext.DomHelper.insertAfter(v.scroller, {
tag: 'textarea',
id: Ext.id(),
value: '',
style: {
'font-size': '1px',
border: '0px none',
overflow: 'hidden',
color: '#fff',
position: 'absolute',
top: v.mainHd.getHeight() + 'px',
left: '0px',
'background-color': '#fff',
margin: 0,
cursor: 'default'
}
}, true);
this.textEl.setOpacity(0.1);
this.textEl.forwardMouseEvents();
this.textEl.on({
mouseover: function(){
Ext.TaskMgr.start(this.changeValueTask);
},
mouseout: function(){
Ext.TaskMgr.stop(this.changeValueTask);
},
scope: this
});
resizeDropArea.call(this);
}
}
// on GridPanel resize, keep scroller height correct to accomodate textarea.
function resizeDropArea(){
if (this.textEl) {
var v = this.view,
sc = v.scroller,
scs = sc.getSize,
s = {
width: sc.dom.clientWidth - v.getScrollOffset() + 2 || (scs.width - v.getScrollOffset() + 2),
height: sc.dom.clientHeight - v.getScrollOffset() + 2 || scs.height
};
this.textEl.setSize(s);
}
}
// on change of data in textarea, create a Record from the tab-delimited contents.
function dataDropped(e, el){
var nv = el.value;
el.blur();
if (nv !== '') {
if (this.fireEvent('beforedatadrop',this,nv,el)){
var store = this.getStore(), Record = store.recordType;
el.value = '';
var rows = nv.split(lineEndRE), cols = this.getColumnModel().getColumnsBy(function(c){
return !c.hidden;
}), fields = Record.prototype.fields, recs = [];
this.fireEvent('datadrop',this,rows);
if (cols.length && rows.length) {
for (var i = 0; i < rows.length; i++) {
var vals = rows[i].split(sepRe), data = {};
if (vals.join('').replace(' ', '') !== '') {
for (var k = 0; k < vals.length; k++) {
var fldName = '';
if(!this.dataDropPluginCfg.xlsColMapper) {
fldName = cols[k].dataIndex;
}
else {
fldName = this.dataDropPluginCfg.xlsColMapper[k];
}
if(!Ext.isEmpty(fldName)) {
var fld = fields.item(fldName);
data[fldName] = fld ? fld.convert(vals[k]) : vals[k];
}
}
if(!Ext.isEmpty(data)) {
var newRec = new Record(data);
recs.push(newRec);
if (!this.dataDropPluginCfg.addBulk){
store.add(newRec);
if (this.dataDropPluginCfg.highlightNewRows){
var idx = store.indexOf(newRec);
this.view.focusRow(idx);
Ext.get(this.view.getRow(idx)).highlight();
}
}
}
}
}
if (this.dataDropPluginCfg.addBulk && recs && recs.length){
store.add(recs);
if (this.dataDropPluginCfg.highlightNewRows){
var idx = store.data.length-1;
this.view.focusRow(idx);
Ext.get(this.view.getRow(idx)).highlight();
}
}
this.fireEvent('afterdatadrop',this,recs);
resizeDropArea.call(this);
}
}else{
el.value = '';
}
}
}
return {
init: function(cmp){
cmp.addEvents({
'beforedatadrop': true,
'datadrop': true,
'afterdatadrop': true
});
cmp.dataDropPluginCfg = Ext.apply({addBulk:true,highlightNewRows:true}, cmp.dataDropPluginCfg);
Ext.apply(cmp, {
changeValueTask: {
run: function(){
dataDropped.call(this, null, this.textEl.dom);
},
interval: 100,
scope: cmp
},
onResize: cmp.onResize.createSequence(resizeDropArea)
});
cmp.getView().afterRender = cmp.getView().afterRender.createSequence(onViewRender, cmp);
}
};
})();
/**
* @cfg dataDropPluginCfg config object with following properties:
* addBulk: boolean, highlightNewRows: boolean, xlsColMapper: Array of dataIndex keys to correspond to excel column index.
*/