Remove context menu / right click in a Ext JS grid - extjs

I have a table grid in Ext Js with a selection.CheckboxModel
I can multi select items in the grid, but it seems like also right click can select items
The question is is there any way to remove right click so it does not select item/s?
Thanks in advance,
Bob

To prevent selection with rigth button you can use this code (with Ext JS 4)...
var allowSelection=true;
...
grid.on('beforeitemmousedown', function(grid, record, item, index, event, eOpts) {
if (event.button==0) allowStreetSelection=true; else allowSelection=false;
});
grid.on('beforeselect', function(grid, record, index, eOpts) {
return allowSelection;
});

To stop the context menu, you can catch the rowcontextmenu event and stop it.
grid.on('rowcontextmenu', function(grid,index,e) { e.stopEvent() });
This may also solve your row selection issue but right-click doesn't select rows for me. What version of ExtJS are you using and on which browsers do you see this problem? On ExtJS 3.3 and Firefox 4 and IE 8-9 I can't reproduce it.
Edit: For Ext 4, containercontextmenu looks to be the event to catch. Returning false from that handler should stop the context menu from appearing. I don't have much experience with Ext 4, so let me know if it works for you.

This worked like a charm for me (EXTJS 4.1.2):
grid.on('beforeitemmousedown', function(grid, record, item, index, event, eOpts) {
return (event.button == 0);
});

We've also met the same problem while using ExtJS4, our solution for now is to modify the original code in extJS.
Find:
} else if (me.isSelected(record) && !e.shiftKey
&& !e.ctrlKey && me.selected.getCount() > 1)
{
me.doSelect(record, keepExisting, false);
You can find them in ext-all.js or in src/selection/Model.js
And change it to:
} else if (me.isSelected(record) && !e.shiftKey && !e.ctrlKey && me.selected.getCount() > 1) {
if (e.button != 0)
keepExisting = true;
else
keepExisting = false;
me.doSelect(record, keepExisting, false);
This code will prevent clear current item selections except u're clicking the item with mouse button 0 (left button).

Related

CheckBox header not marked as checked with collapse tree grid

please look into following images let me know if you have any solution for it,
when I click on select all header checkbox (last column of grid) at that time if grid having row in collapse mode at that time all the record get selected but header checkbox remains unchecked but when I expand that particular record grid then header checkbox get selected please help me with it.
how can we get checked header checkbox while grid data in collapse mode.
enter image description here
enter image description here
Got an answer just override method onHeaderClick see commented lines,
`onHeaderClick: function(headerCt, header, e) {
if (header.isCheckerHd) {
e.stopEvent();
var me = this,
isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');
// Prevent focus changes on the view, since we're selecting/deselecting all records
me.preventFocus = true;
if (isChecked) {
me.deselectAll();
me.toggleUiHeader(false); // added
} else {
me.selectAll();
me.toggleUiHeader(true); // added
}
}
Please find code snippet below
addTreeGrid: function( view, type ) {
var me = this,
grid = null;
grid = Ext.create( 'widget.documentgrid', {
selModel: new Ext.selection.CheckboxModel({
injectCheckbox:'last',
checkOnly: true,
listeners : {//Issue # 7066 : t3281034
beforeselect : function(model, record, index){
if( record.get('status') === 'ANNL' ){
return false;
}
}
}
})
} );

want to enable a combobox only when another combo is selected in extjs

There are two combo boxes and a button.I want a validation i.e. if "combo1" is selected then "combo2" should get enabled and when i select "combo2" then browse button should get enabled.
Mabe something like that (insert text on first combobox):
The combobox2 and button must have this configs:
hidden:true,
disabled:true,
On combobox1:
listeners:{
change: function(combobox,newValue, eOpts){
var combo2 = Ext.ComponentQuery.query('#combo2ItemId')[0];
var button = Ext.ComponentQuery.query('#buttonItemId')[0];
if(!Ext.isEmpty(newValue)) {
combo2.setHidden(false).setDisabled(false);
button.setHidden(true).setDisabled(true);
}
else {
combo2.setHidden(true).setDisabled(true);
button.setHidden(true).setDisabled(true);
}
}
On combobox2:
listeners:{
change: function(combobox,newValue, eOpts){
var button = Ext.ComponentQuery.query('#buttonItemId')[0];
if(!Ext.isEmpty(newValue)) {
button.setHidden(false).setDisabled(false);
}
else {
button.setHidden(true).setDisabled(true);
}
}
I hope this helps!
I guess you may want to disable the second combo and button when the page first shows.
Then You could listen for the change event for each combo and in your handler code disable\enable which ever controls you need to based on the values passed into the handler function arguments.

How do I scroll an ngGrid to show the current selection?

I'm setting the selection of my ngGrid from JavaScript, calling gridOptions.selectItem(). I have multiSelect set to false, so there is only ever one row selected. I'd like the ngGrid to automatically scroll to show the newly selected row, but I don't know how to do this: can anyone help, please?
On a related topic: can I disable row selection by mouse click? If so, how?
Edited to add
I'd also like to disable keyboard navigation of the selected row, if possible.
What worked:
AardVark71's answer worked. I discovered that ngGrid defines a property ngGrid on the gridOptions variable which holds a reference to the grid object itself. The necessary functions are exposed via properties of this object:
$scope.gridOptions.selectItem(itemNumber, true);
$scope.gridOptions.ngGrid.$viewport.scrollTop(Math.max(0, (itemNumber - 6))*$scope.gridOptions.ngGrid.config.rowHeight);
My grid is fixed at 13 rows high, and my logic attempts to make the selected row appear in the middle of the grid.
I'd still like to disable mouse & keyboard changes to the selection, if possible.
What also worked:
This is probably closer to the 'Angular Way' and achieves the same end:
// This $watch scrolls the ngGrid to show a newly-selected row as close to the middle row as possible
$scope.$watch('gridOptions.ngGrid.config.selectedItems', function (newValue, oldValue, scope) {
if (newValue != oldValue && newValue.length > 0) {
var rowIndex = scope.gridOptions.ngGrid.data.indexOf(newValue[0]);
scope.gridOptions.ngGrid.$viewport.scrollTop(Math.max(0, (rowIndex - 6))*scope.gridOptions.ngGrid.config.rowHeight);
}
}, true);
although the effect when a row is selected by clicking on it can be a bit disconcerting.
It sounds like you can make use of the scrollTop method for the scrolling.
See also http://github.com/angular-ui/ng-grid/issues/183 and the following plunker from #bryan-watts http://plnkr.co/edit/oyIlX9?p=preview
An example how this could work would be as follows:
function focusRow(rowToSelect) {
$scope.gridOptions.selectItem(rowToSelect, true);
var grid = $scope.gridOptions.ngGrid;
grid.$viewport.scrollTop(grid.rowMap[rowToSelect] * grid.config.rowHeight);
}
edit:
For the second part of your question "disabling the mouse and keyboard events of the selected rows" it might be best to start a new Question. Sounds like you want to set your enableRowSelection dynamically to false? No idea if that's possible.
I believe I was looking for the same behavior from ng-grid as yourself. The following function added to your gridOptions object will both disallow selection via the arrow keys (but allow it if shift or ctrl is held down) and scroll the window when moving down the list using the arrow keys so that the currently selected row is always visible:
beforeSelectionChange: function(rowItem, event){
if(!event.ctrlKey && !event.shiftKey && event.type != 'click'){
var grid = $scope.gridOptions.ngGrid;
grid.$viewport.scrollTop(rowItem.offsetTop - (grid.config.rowHeight * 2));
angular.forEach($scope.myData, function(data, index){
$scope.gridOptions.selectRow(index, false);
});
}
return true;
},
edit: here is a plunkr:
http://plnkr.co/edit/xsY6W9u7meZsTJn4p1to?p=preview
Hope that helps!
I found the accepted answer above is not working with the latest version of ui-grid (v4.0.4 - 2017-04-04).
Here is the code I use:
$scope.gridApi.core.scrollTo(vm.gridOptions.data[indexToSelect]);
In gripOptions, you need to register the gridApi in onRegisterApi.
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
},
var grid = $scope.gridOptions.ngGrid;
var aggRowOffsetTop = 0;
var containerHeight = $(".gridStyle").height() - 40;
angular.forEach(grid.rowFactory.parsedData, function(row) {
if(row.entity.isAggRow) {
aggRowOffsetTop = row.offsetTop;
}
if(row.entity.id == $scope.selectedId) {
if((row.offsetTop - aggRowOffsetTop) < containerHeight) {
grid.$viewport.scrollTop(aggRowOffsetTop);
} else {
grid.$viewport.scrollTop(row.offsetTop);
}
}
});

How to prevent itemclick event on check change in Ext Js Tree

I added two listeners 'check change' and 'item click' in Ext.tree.Panel. But i noticed that,
when ever the check change occurs then it is also triggering item click event also. I wish to prevent this item click event.
listeners : {
checkchange: function(node, checked, eOpts){
alert('this is check change');
},
itemclick : function(obj, record, item, index, e, eOpts){
alert('this is item click');
}
}
This are the listeners in Ext tree. On check change i wish to get 'this is check change' this alert only. How it is possible ?
You can use event getTarget method to check DOM of the checkbox. The complete solution is below:
onItemClick: function( self, record, item, index, eventObj, eOpts ) {
var colIdx = eventObj.getTarget('.x-grid-cell').cellIndex;
if (colIdx===0) { // Apply item event click to the first column only
var node=self.getTreeStore().getNodeById(record.internalId);
if (!eventObj.getTarget('.x-tree-checkbox',1,true)) {
record.set('checked',!record.get('checked'));
this.fireEvent('checkchange', node, record.get('checked'));
}
}
}
Lame solution !
I was able to limit the script only to the 'itemclick'.
Works well in ExtJs 5.1.1 and probably in all versions where css checkbox class name is 'x-tree-checkbox'
listeners : {
itemclick : function(panel, record , item , index, event){
var clazz = '';
if(event.target.classList != null){
clazz = event.target.classList[0];
}
if(clazz != 'x-tree-checkbox'){
...
}
}
}
If you are clicking the checkbox to change its value the itemclick event will always fire before the checkchange event. If you dont wish for anything to happen on the itemclick event, simply dont define it (remove the listener).
Have you tried to implement the 'beforeitemclick' event? it fires when you click the item, and inside this handler you can implement the checkchange.

Jquery - Accordion - active state

I've searched for the answer on this forum, but haven't been able to find it.
Here is my question:
I want disable the possibility to open the first and the second pane of my accordion, and allow it to open only when if want. It's like to make some panes disabled and some enabled.
I've searched with this code :
$( "#accordion" ).bind( "accordionchangestart", function(event, ui) {
var active = $(this).accordion( "option", "active" );
if(active == 0)||(active == 1)){
preventDefault();
}
});
It works only for the second pane ( == 1) because when the state is closed, it's considered as false, and false == 0 for jquery.
I've tried searching if the selected pane is the first with the ui-state-active class, but this is too late, when the class appears, the pane is opened, and that's what i want to prevent.
Any idea ?
Thanks
If you are using jQuery UI's Accordion than what you should do is use the changestart event to check which one is clicked and do whatever you want to do.
Use this to check the current state:
$( "#accordion" ).accordion({changestart: function(event, ui) {
alert(ui.newHeader[0].textContent);
}});
Yo can also change the current option like this:
$("#accordion").accordion("activate", 3);
You can find events documentation here:
http://jqueryui.com/demos/accordion/#events
And here is the activate method documentation:
http://jqueryui.com/demos/accordion/#method-activate
If I want to take action only when expanding:
var active = $(this.container).accordion('option', 'active');
if (!active && $.type(active) === 'boolean') {
//No action
return;
}
//Loading some data inside accordion content

Resources