PDA

View Full Version : Ext.ux.grid.CellContextMenu



d.zucconi
18 Oct 2011, 12:40 AM
Plugin to enable a context menu for the grid cells, configured according to the data of each cell.
Please refer to code documentation to discover plugin features and capabilities.

Source code
18/10/11 - Preview release


/**
* Plugin that enables grid cell context menu.
* The configuration for a cell context menu can be defined on each grid column
* configuration using special attribute {@link #cellContextMenu}.<br>
* This attribute can be:
* <ul>
* <li>An Ext.menu.Menu configuration object (static menu initialization)</li>
* <li>A function that returns an Ext.menu.Menu configuration object (dinamic menu configuration)</li>
* </ul>
* If the cellContextMenu is a function, it will be called when cell context menu event is triggered.
* This function will be called using the grid as scope and a <code>gridCellData</code> object as parameter.
* <h2>GridCellData Object</h2>
* The <code>gridCellData</code> object has the following attributes:
* <ul>
* <li><code>header</code>: the cell grid header</li>
* <li><code>model</code>: the cell grid row model</li>
* <li><code>el</code>: the cell element</li>
* <li><code>value</code>: the cell grid value (from model and dataIndex)</li>
* <li><code>grid</code>: the grid</li>
* </ul>
* <h2>Menu items special features</h2>
* Each item of the generated menu has a special attribute <code>gridCellData</code>, an object with
* the attributes listed before.
* Using this special item attribute you can manage grid data with menu item handler:
* <code>
* handler: function(item)
* {
* alert item.gridCellData.value;
* }
* </code>
* <h2>Events enabled on Grid</h2>
* This plugin also enables some events on grid:
* <ul>
* <li><code>beforecellcontextmenu</code></li>
* <li><code>cellcontextmenu</code></li>
* </ul>
*/
Ext.define('Ext.ux.grid.CellContextMenu',{

ptype: 'gridcellcontextmenu',

alternateClassName: ['Ext.ux.grid.CellMenu'],

requires: [
'Ext.menu.Menu'
],

menu: null,

init: function(grid)
{
this.grid = grid;
this.grid.on({
scope: this,
itemcontextmenu: this.onItemMenu,
destroy: this.destroyMenu
});

this.grid.addEvents(
/**
* <b>Event enabled on grid</b>, fired before the cell context menu is shown.
* Return <code>false</code> to avoid menu show.
* @event
* @param {Object} gridCellData The grid cell data object (please refer to class doc to know attributes of this object)
* @param {Object} menuConfig The configuration of the context menu, as specified on grid column config <code>cellContextMenu</code> attribute
*/
'beforecellcontextmenu',
/**
* <b>Event enabled on grid</b>, fired after the cell context menu is shown.
* @event
* @param {Object} gridCellData The grid cell data object (please refer to class doc to know attributes of this object)
* @param {Ext.menu.Menu} menu The context menu shown
*/
'cellcontextmenu');
},

onItemMenu: function(view, model, item, index, ev, opts)
{
var cell = ev.getTarget(view.cellSelector);
if(cell)
{
var header = view.getHeaderByCell(cell);
if(header)
{
this.onCellClick(cell, model, header, ev);
}
}
},

onCellClick: function(cell, model, header, ev)
{
/**
* @cfg {Object} cellContextMenu
* <b>Configuration parameter enabled on each grid column config</b>, it can be an
* <code>Ext.menu.Menu</code> configuration object or a function that returns a menu configuration object.
* Please refer to the documentation of the plugin to get the parameters passed to this function.
*/
if(!header.cellContextMenu)
return false;

var gridCellData = {
header: header,
model: model,
el: cell,
value: model.get(header.dataIndex),
grid: this.grid
};

var mc = header.cellContextMenu;
if(Ext.isFunction(mc))
{
mc = mc.call(this.grid, gridCellData);
}

if(this.grid.fireEvent('beforecellcontextmenu', gridCellData, mc) === false)
return;

ev.preventDefault();

this.destroyMenu();

this.menu = Ext.create('Ext.menu.Menu',mc);
this.menu.gridCellData = gridCellData;
this.menu.items.each(function(mi){
mi.gridCellData = gridCellData;
});
this.menu.showBy(cell);
this.grid.fireEvent('cellcontextmenu', gridCellData, this.menu);
},

destroyMenu: function()
{
if(!this.menu)
return;
if(this.menu.isVisible())
this.menu.hide();
Ext.destroy(this.menu);
this.menu = null;
}
});


Use case
Into your grid configuration:


...
plugins: [Ext.create('Ext.ux.grid.CellContextMenu')],
columns: [
{
text: "Number",
dataIndex: "DOC_NUMBER",
width: 100,
cellContextMenu: function(cellData)
{
return {
items: [
{
text: 'Voce 1',
handler: function()
{
alert(this.gridCellData.header.dataIndex + ' = ' + this.gridCellData.value);
},
disabled: cellData.value != 'R547'
},
{
text: 'Voce 2'
}]};
}
},...