ExtJS 4.2 Tree highlight selected row on cell editing - extjs

I have a tree panel with 4 columns:
var cellEditing = Ext.create('Ext.grid.plugin.CellEditing',{
pluginId : 'cellEditing',
clicksToEdit: 1
});
var tree = new Ext.tree.Panel({
store:treestore,
plugins : [
cellEditing
],
selModel:{
selType:'cellmode'
},
defaults:{
tdCls:'greyColumn'
},
columns:[
somecolumns
]
});
And in my css I have the style:
.x-grid-row .greyColumn {
background-color:#f2f2f2;
}
I´m trying to add this piece of code in the selModel definition:
listeners: {
select: function (cellModel, record, rowIndex) {
cellModel.view.addRowCls(rowIndex, 'style');
},
deselect: function (cellModel, record, rowIndex) {
cellModel.view.removeRowCls(rowIndex, 'style');
},
scope: this
}
And in my css the "style" definition:
.x-grid-row.style .x-grid-cell {
background-color: #edbcb4 !important;
}
When the tree loads, i see the columns with the background grey, but when I select one cell to edit, it turns red for a moment and returns to grey and I don't know how to fix it or avoid it. I want the row of the cell i´m editing red, not returning to grey.

Use edit and beforeedit event's in your celledit component form styled row
Fiddle

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.

ExtJS 4.2 treepanel highlight row on cell selection

I have a treepanel with cell selection:
selModel: Ext.create('Ext.selection.CellModel', {
listeners: {
select: function (cellModel, record, rowIndex) {
var myGrid = Ext.ComponentQuery.query('view #grid')[0];
myGrid.getView().addRowCls(rowIndex, 'style');
},
deselect: function (cellModel, record, rowIndex) {
var myGrid = Ext.ComponentQuery.query('view #grid')[0];
myGrid.getView().removeRowCls(rowIndex, 'style');
},
scope: this
}
}),
And the columns have tdCls property:
tdCls : 'greyColumn/yellowColumn', //It depends on the position
- greyColumn/yellowColumn STYLE -
.x-grid-row .greyColumn{
background-color:#f2f2f2;
}
.x-grid-row .yellowColumn {
background-color:#ffffcc;
}
- selModel STYLE -
.x-grid-row .style{
background-color: red !important;
}
The tdCls attribute works perfect, and the cells are coloured correctly.
But when I select a cell, the row is not getting red color.
Any idea about what am I doing wrong??
You change the background-color of the element tr which is a level lower.
Look at my fiddle
You must change the background-color of the cells, even if you want to change the background-color of row.

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

ExtJs - Checkbox selection model, disable checkbox per row

I have a grid with a checkbox selection model.
Ext.define('Mb.view.ship.OrdersGrid', {
extend: 'Ext.grid.Panel',
selType: 'checkboxmodel',
selModel: {
injectCheckbox: 0,
pruneRemoved: false
},
...
There are some rows that shold not be selectable, based on a value in a field.
In a normal column, I can intervene in the display with renderer and hide the cell content with css (metadata.tdCls), but for the auto generated checkbox column, I cannot find a method to disable or hide the checkbox on a row basis.
Does anyone have an idea how to do this ?
You simply use the beforeselect event of the grid. Returning false, will not allow the selection. Check the documentation.
Ext.define('Mb.view.ship.OrdersGrid', {
extend: 'Ext.grid.Panel',
selType: 'checkboxmodel',
selModel: {
injectCheckbox: 0,
pruneRemoved: false
},
listeners: {
beforeselect: function(grid, record, index, eOpts) {
if (record.get('yourProperty')) {//replace this with your logic.
return false;
}
}
}
..........
If you really want to hide the checkbox, you could add CSS classes for your grid rows, and using them you could may be hide them. Check this answer for a solution.
In ExtJS 6 overriding renderer will not work.
You can get around that by defining viewConfig with getRowClass:
getRowClass: function(record) {
var classes = '';
if (!record.get('available')) {
classes += ' selection-disabled';
}
return classes;
}
Then in your CSS add this:
.selection-disabled .x-selmodel-column {
visibility: hidden;
}
That will hide selection checkbox.
Now to disable selection by clicking on a row use the standard method. I.e. add a beforeselect to listeners to selModel:
selModel: {
selType: 'checkboxmodel',
showHeaderCheckbox: false,
listeners: {
beforeselect: function(grid, record) {
if (!record.get('available')) {
return false;
}
}
}
},
CheckboxSelectionModel also has a renderer.
var sm = new Ext.grid.CheckboxSelectionModel({
checkOnly : true,
renderer : function(v,p,record) {
// First condition : show
if (record.data.XXX == 'YYYY') return '<div class="x-grid3-row-checker"> </div>';
// else hide
else return '';
},
header: ''
});
https://www.sencha.com/forum/showthread.php?122496-How-to-hide-certain-checkbox-in-a-CheckboxSelectionModel
Returning empty '' also disables checkbox selection, not only by hiding it but also adding unselectable="on" to the parent div.
Don't know about doing it inside an Ext.define (never had the need to extend) , but seems feasible.
UPDATE: Despite having unselectable="on", clicking on the row (if enabled), or using the header checkbox (select-all) will select "disabled" rows. It may be a good idea to implement a listener then.

ExtJS: add button to htmleditor

I am using ExtJS and I have a htmleditor in my form. I would like to add a custom button to that element (for example after all other buttons like alignments, font weights, ...). This button should basically insert a standard template in the htmlfield. Being this template html, the behaviour of the button should be like this
Switch to HTML mode (like when pressing Source button)
Insert something
Switch back to WYSIWYG mode (like when pressing the Source button again)
Thanks for your attention
You don't need to switch to HTML mode. Just use the insertAtCursor function with the HTML template.
I made this easy example of how to add button which inserts a horizontal ruler (<hr> tag):
Ext.ns('Ext.ux.form.HtmlEditor');
Ext.ux.form.HtmlEditor.HR = Ext.extend(Ext.util.Observable, {
init: function(cmp){
this.cmp = cmp;
this.cmp.on('render', this.onRender, this);
},
onRender: function(){
this.cmp.getToolbar().addButton([{
iconCls: 'x-edit-bold', //your iconCls here
handler: function(){
this.cmp.insertAtCursor('<hr>');
},
scope: this,
tooltip: 'horizontal ruler',
overflowText: 'horizontal ruler'
}]);
}
});
Ext.preg('ux-htmleditor-hr', Ext.ux.form.HtmlEditor.HR);
Ext.QuickTips.init();
new Ext.Viewport({
layout: 'fit',
items: [{
xtype: 'htmleditor',
plugins: [new Ext.ux.form.HtmlEditor.HR()]
}]
});
You can see it running at: jsfiddle.net/protron/DCGRg/183/
But I really recommend you to check out HtmlEditor.Plugins (or ateodorescu/mzExt for ExtJS 4). There you can find a lot more about adding custom buttons, for instance, how to enable/disable the buttons when something is selected, put separators, etc.
You also can use ExtJS.ux.HtmlEditor.Plugins : https://github.com/VinylFox/ExtJS.ux.HtmlEditor.Plugins
In addition to #proton great answer above, there's another way to insert buttons to the toolbar, different from adding them to the end.
In my answer i'll write it as a new control named 'RichTextBox' (and not as a plugin) but this can be done in any other way:
Ext.define('Ext.ux.form.RichTextBox', {
extend: 'Ext.form.field.HtmlEditor',
xtype: 'richtextbox',
enableSourceEdit: false, // i choose to hide the option that shows html
initComponent: function () {
this.on('render', this.onRender, this);
this.callParent();
},
/**
* Insert buttons listed below to the html-editor at specific position.
* handler is implemented using 'execCommand':
* https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
*/
onRender: function () {
var me = this;
var tb = me.getToolbar();
var btns = {
StrikeThrough: {
//xtype: 'button', // button is default item for this toolbar
itemId: 'btnStrikeThrough',
iconCls: 'x-toolbar-strikethrough ', //choose icon with css class
enableOnSelection: true,
overflowText: 'StrikeThrough',
tooltip: {
title: 'StrikeThrough',
text: 'Toggles strikethrough on/off for the selection or at the insertion point'
},
handler: function () {
this.getDoc().execCommand('strikeThrough', false, null);
},
scope: this,
},
/** Seperator */
sep: "-"
};
tb.insert(5, btns.StrikeThrough); // insert button to the toolbar
//tb.insert(10, btns.sep); // add seperator
//tb.remove(26); // remove button, seperator, etc.
this.callParent(); //important: call regular 'onRender' here or at the start of the foo
}
});

Resources