I have a grid with really high rows like this: https://fiddle.sencha.com/#view/editor&fiddle/2581
By default, when a grid row is clicked, the row scrolls into view. For some reason, I don't want that. It should be selected/focused, but not scrolled into view if it is already partly visible.
Take my example, and scroll such that the border between the first and the second is in the middle of the screen. Click either row, and it will be scrolled into view, and the values I have to see from the other row are no longer visible.
How can I prevent that automatism?
To stop scrolling you can give navigationModel as empty object in viewConfig of grid.
viewConfig: {
navigationModel: {}
}
But, it will also stop scrolling of grid using arrow keys.
So, as ankit chaudhary tells us, one needs to remove the navigationModel. I thought a navigationModel could be useful and decided to override the navigationModel to adapt it to my requirement:
Ext.define('MyApp.override.NavigationModel', {
override : 'Ext.grid.NavigationModel',
scrollOnFocus: true,
constructor: function(config) {
this.callParent(arguments);
if(Ext.isBoolean(config.scrollOnFocus)) this.scrollOnFocus = config.scrollOnFocus;
},
onCellMouseDown: function(view, cell, cellIndex, record, row, recordIndex, mousedownEvent) {
var actionableEl = mousedownEvent.getTarget(this.isFocusableEl, cell);
if (!this.scrollOnFocus && !view.actionableMode && mousedownEvent.pointerType !== 'touch' && mousedownEvent.position.column.cellFocusable !== false && !actionableEl) return;
this.callParent(arguments);
},
onItemMouseDown: function(view, record, item, index, mousedownEvent) {
var me = this,
scroller;
if (!mousedownEvent.position.cellElement && (mousedownEvent.pointerType !== 'touch')) {
if (!view.enableTextSelection) {
mousedownEvent.preventDefault();
}
me.attachClosestCell(mousedownEvent);
if (me.scrollOnFocus && !me.position.isEqual(mousedownEvent.position)) {
me.setPosition(mousedownEvent.position, null, mousedownEvent);
}
scroller = view.getScrollable();
if (scroller) {
scroller.restoreState();
}
}
}
});
Now I can add to my grid's viewConfig a customized navigationModel:
viewConfig: {
navigationModel:{
type:'grid',
scrollOnFocus: false
}
}
and the grid does no longer scroll on a mouse click.
For focusing set focusRow wheerever you want
grid.view.focusRow(grid.store.getAt(0));
Related
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.
I have a grid, with a selection model that does allow the selection of a row only under certain conditions.
When I click on a row, it gets focussed (it becomes darker gray). I want to add a button, that acts on the currently focussed row.
Since the selection is deactivated, I cannot use the normal way
grid.getSelectionModel().getSelection()
because there is no selection. How can I access the focussed row ?
Add this listener to your grid to get information about the focused row.
Ext.create('Ext.grid.Panel', {
...
listeners: {
afterrender: function(component){
component.getSelectionModel().on({
focuschange: function (view, oldFocused, newFocused, eOpts) {
console.log(newFocused);
}
});
}
}
});
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).
Is there a standard way to highlight active row in a grid like in attached screen?
I mean having a grid, with cellmodel selection type, when clicking on an item in the grid, it highlights the cell. I would like to highlight the active row at the same time.
It is very useful when gird contain a lots of data to be analysed,
when selecting cell, and entire row (maybe collumn?) needs to be highlighted.
Thanks for your help guys. We did it :) Here is the one possible solution :
selModel: Ext.create('Ext.selection.CellModel', {
listeners: {
select: function (cellModel, record, rowIndex) {
var myGrid = this.items.get('gridItemId');
myGrid.getView().addRowCls(rowIndex, 'row-style');
},
deselect: function (cellModel, record, rowIndex) {
var myGrid = this.items.get('gridItemId');
myGrid.getView().removeRowCls(rowIndex, 'row-style');
},
scope: this
}
}),
you can use addRowCls method of grid which Adds a CSS Class to a specific row.
http://docs.sencha.com/ext-js/4-0/#/api/Ext.grid.View-method-addRowCls
Even if you are using the CellSelectionModel, you could easily apply styles/classes to the row the selected cell is in. If you take a look at the events for CellSelectionModel, you'll see the cellselect actually returns the rowIndex.
cellselect : ( SelectionModel this, Number rowIndex, Number colIndex )
So, what you could so is something like the following:
// we'll say you have your Grid stored in a variable, grid
CellSelectionModel ...({
listeners: {
'cellselect': function(selModel, rowIndex) {
var cellRow = grid.getView().getRow(rowIndex);
Ext.fly(cellRow).addClass('selectedRow')
// do any other logic with the actual DOM element here
}
})
In ExtJS 4, selecting a row in a Grid Panel (by clicking it), and pressing the spacebar selects and de-selects the row. It was not like this in ExtJS 3, and I would like to disable this feature.
Any ideas? I've begin looking into Ext.util.KeyMap to see if I could override it somehow. Thanks in advance.
You have to override the onKeyPress method of the Ext.selection.RowModel. The shipped implementation is
onKeyPress: function(e, t) {
if (e.getKey() === e.SPACE) {
e.stopEvent();
var me = this,
record = me.lastFocused;
if (record) {
if (me.isSelected(record)) {
me.doDeselect(record, false);
} else {
me.doSelect(record, true);
}
}
}
}
Unfortunately there currently is no configuration switch to turn off that behavior.