Context menu in grid in ExtJS - extjs

I have a two context menu items inside my grid. The first one is "delete" and the second one is Disable or Enable. Delete context menu I have added as below
var contextMenu = Ext.create('Ext.menu.Menu', {
controller: 'sites',
width: 250,
plain: true,
items: [{
text: 'Delete',
handler: function () {
},
}]
Now I wanted to add Disable or Enable inside the items as a context menu. By enable or disable I mean I need to check the state of that particular row of the grid i.e. if the state of the row is enabled then "Disable" option should be come in the context menu and if the state is disables then the "Enable" option should be come in the context menu. How can I check the state of the row and how can I put if else condition inside my items? Below is the column for checking the enabling of the row.
columns: [
{text:'Active',dataIndex:'enabled',flex:1 },
]

You can use an actioncolumn to do so. It renders an icon in the grid cell, where you can link a function thanks to the handler config.
Here you can check with the record parameter whether the selected row is active, and render conditionally the right option; for example:
handler: function(view, rowIndex, colIndex, item, e, record, eOpts) {
if (record.data.active) {
openDisableMenu()
} else {
openEnableMenu()
}
}

Related

Adding enabling and disabling as context menu on a grid in extjs

Hi I have added one context menu on my grid which will perform the enable and disable functionality for selected row. I am new to ExtJs. I have added below listener for the grid. How to add enable and disable functionality for the grid row?
listeners: {
itemcontextmenu: function (grid, record, item, index, e) {
var contextMenu = Ext.create('Ext.menu.Menu', {
controller: 'grid-controller',
width: 165,
plain: true,
items: [{
text: 'Disable',
listeners: {
click: {fn: 'disable', extra: record}
},
}]
});
e.stopEvent();
contextMenu.showAt(e.getXY());
}
}
This is not a copy-paste answer, but going through the following steps with doing your own research you can solve your problem.
1. Create the context menu only once and destroy it
In you code, the context menu is created every time when the user opens up the menu on the grid. This is not good. Instead, create the context menu only once when the grid is created, and destroy it when the grid is destroyed. Something like this:
Ext.define('MyGrid', {
extend: 'Ext.grid.Panel',
initComponent : function() {
this.callParent();
this.MyMenu = Ext.create('Ext.menu.Menu', {
items: [...]
});
this.on({
scope : this,
itemcontextmenu : this.onItemContextMenu
});
},
onDestroy : function() {
if (this.MyMenu) {
this.MyMenu.destroy();
}
},
onItemContextMenu : function(view, rec, item,index, event) {
event.stopEvent();
this.MyMenu.showAt(event.getXY());
}
});
2. Store enabled / disabled state in the record
For the next step to work, records in your grid must contain whether the corresponding row is enabled or disabled. In the context menu, when user selects enabled / disabled, store this status like this, get record of the row where the context menu was displayed from:
record.set('myDisabledState', true); // or false
It is important to store the disabled state (and not enabled), because when your grid initially is rendered, these values won't be in the records, so record.get('myDisabledState') will evaluate to FALSE, and that is the desired behaviour, if you want to start with every row being able to be selected.
3. Disable selection
Now you can add a beforeselect listener to your grid, see documentation. This listeners receives record as parameter, and if you return false from this listener, the selection will be canceled. So in this listener simply add:
listeners: {
beforeselect: function ( grid, record, index, eOpts ) {
return !record.get('myDisabledState');
}
}
4. Apply formatting - OPTIONAL
It is likely that you want to add different formatting for disabled rows, for example grey colour. The easiest way to do it is to add a custom CSS style to your Application.scss file:
.my-disabled-row .x-grid-cell-inner {
color: gray;
}
Finally add getRowClass configuration to your grid, it will receive the current record being rendered, and you can return the above custom CSS style when the row is disabled:
Ext.define('MyGrid', {
// your grid definition
,
viewConfig: {
getRowClass: function (record, rowIndex, rowParams, store) {
if (record.get('myDisabledState')) {
return "my-disabled-row";
}
}
}
});
In this last part, when row is not disabled, it will return nothing, so default formatting will be used.

How to disable Delete icon in Extjs grid

I have a sample code from extjs, the action is part of multi column of an column where I have edit, delete, duplicate. I want to disable the delete icon based on another field value. I have an another column called IS_USED which returns true/false. The delete button should be disable if IS_USED is true.
I tried to write the handler within action but is not working.
I am new in extjs, any help or workaround is appreciable.
action: {
iconCls: 'x-icon-cross-on',
text: terms.del,
url: url.destroy,
useAjax: true,
confirm: terms.confirm,
handler: function(grid, record, action, domEl, response) {
if ( !response.success) {
test.ui.Msg.flash(response.message, test.ui.Msg.ERR);
javascript.scroll(0,0);
} else {
test.ui.Msg.success(response.message);
grid.getStore().reload();
}
}
}
The best practice is just bind the "disabled" property to the button directly based on the record value.
first, set viewModel:true to the grid.
{
xtype: 'grid',
//add this below
itemConfig:{
viewModel:true
},
//....others props like columns, with,etc....
and the last, in your button add this:
action: {
iconCls: 'x-icon-cross-on',
//add this
bind:{
disabled:"{record.IS_USED}" //the logic is placed here
},
//.....other props....
You can also bind any other bindable properties as like hidden, text, etc by using this trick.
Hope this can help you.

ExtJS 4, how to multi-select grid row as well as single row is also clickable?

I am trying to create a grid using extjs 4.2.2. The grid contains several rows, if I click one row, then pops up another page which displays the detail info of that row.
The grid is in a panel, so the view code is:
Ext.define("Application.view.foo.Panel", {
extend: "Ext.panel.Panel",
cls: 'foo.panel'
...
items: [
{
itemId: "foo-bar",
xtype: "grid",
...
,selType: 'checkboxmodel'
,columns: [
xtype: 'templatecolumn'
and the code of listening row select event in controller is like:
"panel[cls~=foo.panel] #foo-bar": {
select: function(selectionModel, record, index) { .... }
Now, I am going to add check box for each row in order to mass edit, I added selType: 'checkboxmodel', but the problem is that I cannot click the check box: if I click the box, it goes the the detail page, not just being 'checked', cuz the code in controller listens that 'row click' event.
Is there any suggestions to implement it? Thanks in advance.
I would suggest to change your row click listener to view row details with action column.
{
xtype:'actioncolumn',
width:50,
items: [{
// Url is just for example (not working)
icon: 'extjs/examples/shared/icons/fam/showDetails.png', // Use a URL in the icon config
tooltip: 'Show details',
handler: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
// do your functionality here...
}
}
In every row will appear an icon, and then you will have possibility to multiselect rows and to look details of every row as well. Hope that helps.
Try to listen on cellclick event instead.
cellclick: function(view, td, cellIndex, record, tr, rowIndex, e, eOpts) {
if(cellIndex != your_checkbox_column) {
//do your info page stuff here
}
}

Why does clicking icon in an ExtJS 4 grid panel actioncolumn not select the row?

I have a grid panel with an actioncolumn.
There is an icon in the actioncolumn, and its click handler works fine.
But when I click the icon, in the click handler I want to access the selected row, but it seems no row is selected.
Is this expected? Do I need to manually set the selected row when an actioncolumn icon is clicked?
If you want to select row also after user click on icon in actioncolumn just set actioncolumn stopSelection config property to false:
{
xtype:'actioncolumn',
stopSelection: false,
items: [{
...
}]
}
However common use case how to access row's record when user click on icon in action column is get index of the row where user click on the action column icon and get record from store at this index:
{
xtype:'actioncolumn',
items: [{
tooltip: 'Edit',
handler: function(grid, rowIndex, colIndex) {
// get record at index of row where user click on icon in action column
var record = grid.getStore().getAt(rowIndex);
// do action with record ...
}
}]
}

gridpanel right click to delete column

I'm trying to make functionality for deleting column from grid, but I have problem with detecting on which column user right clicked (right click > context menu with delete option).
For the moment I'm displaying the contextMenu something like that
viewConfig: {
stripeRows: true,
listeners: {
itemcontextmenu: function(view, rec, node, index, e) {
e.stopEvent();
contextMenu.showAt(e.getXY());
return false;
}
}
},
You could attach the handler to the contextmenu event for every column, that would give you access to the Column. Then you could refresh the columnmodel by using the setConfig function passing in the new array of columns (minus the one you just deleted).

Resources