How to disable Delete icon in Extjs grid - extjs

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.

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.

Context menu in grid in 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()
}
}

ExtJS: Show/hide control on checkbox selectionchange

I have an ExtJS check-tree ExtJS Check Tree that I am trying to add some control to based on items checked/unchecked. It doesn't seem to fire correctly though.
Here is a Fiddle Example
When checkbox 'A' is selected, I want to hide the textfield, 'testValue', which works, but then if I unselect checkbox 'A', I want to show the textfield, 'testValue', which does not work.
For this test I am merely looking to see if the selections.selected.length === 0. However, when I unselect any of the checkboxes, the listener does not seem to be firing, since the alert message is not getting triggered - plus, if I then try to reselect the check box again it still does not fire.
I would use a selection Model (as outlined below) to achieve this (since I know it works), but then this places checkboxes on all my tree items when I just want to have the leaf nodes with checkboxes.
selModel: {
type: 'checkboxmodel',
listeners: {
selectionchange: 'onCheckedNodesChange'
}
}
Any suggestions would be most welcome!
EDIT
Adding allowDeselect: true and a listener for select and deselect sort of worked (I updated the Fiddle to exhibit the behavior):
selModel: {
allowDeselect: true,
listeners: {
deselect: function(model, record, index) {
text = record.get('text');
alert(text);
},
select: function(model, record, index) {
text = record.get('text');
alert(text);
}
}
},
I want to make sure that when 'A' is selected, the textfield remains hidden, but if you select another item in the list and then deselect it, the textfield returns.
I am trying to use the getChecked() method alone with when selectionchange event occurs. However, this only seems to return data when I do a submit (for example, on the Get checked nodes control). Any suggestions would be most welcome. This should not be so difficult.
For tree panel we have checkchange event it is similar to the selectionchange event.
http://docs.sencha.com/extjs/4.2.5/#!/api/Ext.tree.Panel-event-checkchange
checkchange( node, checked, eOpts )
Fires when a node with a checkbox's checked property changes
Parameters
node : Ext.data.TreeModel
The node who's checked property was changed.
checked : Boolean
The node's new checked state
eOpts : Object
The options object passed to Ext.util.Observable.addListener.
var fields = [
{
name: 'column'
},
{
name: 'leaf',
type: 'boolean'
},
{
name: 'checked',
type: 'boolean'
},
{
name: 'cls',
type: 'string',
defaultValue: 'x-tree-noicon'
},
];
this.dataModel = Ext.define('Filter-' + this.getId(), {
extend: 'Ext.data.Model',
fields: fields,
});
columns: [
{
xtype: 'treecolumn',
width: 200,
itemId: "filter",
dataIndex: 'column' ,
renderer: function (val, metaData, r) {
},
scope: this,
},
],
listeners: {
'checkchange': Ext.bind(function (node, checked,eOpts) {
},
scope: this
The checkboxes you are seeing are not part of the selection behaviour. Instead, they come from the checked configuration on the NodeInterface class.
Your tree panel is using the default selModel, which is row-based selection, with no deselect option. If you want the in-tree checks to control the selection, you'll need to configure that manually, probably by listening to change events from the store.
OTH, if all you care about is finding out which items are checked or not, you can use the getChecked() method on the TreePanel

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
}
}

Switch from textfield to displayfield with ExtJS4

I have created a form that displays values in plain displayfields.
There is an "edit" button next to the form and once clicked by the user, the displayfields should switch to being textfields and will, therefore, make the data editable.
This, I am guessing, would be achieved by having two identical forms, one editable and one not and one or the other would be visible, based on the user having clicked the button. Another way, perhaps, is to have the xtype dynamically selected upon clicking the button.
Can anybody point me towards a certain direction in order to do this? I am a complete newbie to ExtJS and only just started learning ExtJS4.
Thank you in advance.
M.
Start by rendering all fields as input fields with disabled:true. Then use this for the Edit button handler:
...
form.getForm().getFields().each(function(field) {
field.setDisabled( false); //use this to enable/disable
// field.setVisible( true); use this to show/hide
}, form );//to use form in scope if needed
Ext.getCmp('yourfieldid').setFieldStyle('{color:black; border:0; background-color:yourcolor; background-image:none; padding-left:0}');
Ext.getCmp('yourfieldid').setReadOnly(true);
You can toggle based on a property isEditable. Then when you click the button you change the property and just remove and add the form. It makes it cleaner if you are switching back and forth.
Ext.define('E.view.profile.information.Form', {
extend: 'Ext.form.Panel',
xtype: 'form',
title: 'Form',
layout: 'fit',
initComponent: function () {
this.items = this.buildItems();
this.callParent();
},
buildItems: function () {
return [this.buildInvestmentPhilosophy()];
},
buildInvestmentPhilosophy: function () {
var field = {
name: 'investmentPhilosophy',
xtype: 'displayfield',
editableType: 'textarea',
grow: true,
maxLength: 6000,
value: '---',
renderer: E.Format.textFormatter
};
this.toggleEditingForForm(field);
return field;
},
toggleEditingForForm: function (form) {
if (this.isEditable) {
Ext.Array.each(form, this.configureFieldForEditing, this);
}
},
configureFieldForEditing: function (field) {
if (field.editableType) {
field.xtype = field.editableType;
}
}
});
You can also try to have two items : a displayfield and a textfield with the same data source and you could hide/show the right item with your button handler.
You should not have any CSS problems
(If you did not have CSS problems I would enjoy to see you code)

Resources