Ext.grid.cell.Tree collapse and expand method should fire nodecollapse and nodeexpand with the Ext.grid.Row that was collapsed/expanded
https://docs.sencha.com/extjs/7.3.1/modern/Ext.grid.Tree.html#event-nodecollapse
https://docs.sencha.com/extjs/7.3.1/modern/Ext.grid.Tree.html#event-nodeexpand
Instead of that, we are getting a null parameter
Should override both methods and replace me.parent with me.row
Ext.define('Override.grid.cell.Tree', {
override: 'Ext.grid.cell.Tree',
collapse: function() {
var me = this;
me.getGrid()
.fireEventedAction('nodecollapse', [/*me.parent*/ me.row, me.getRecord(), 'collapse'], 'doToggle', me);
},
expand: function() {
...
tree.fireEventedAction('nodeexpand', [/*me.parent*/ me.row, record, 'expand'], 'doToggle', me);
...
}
Related support issue : EXTJS-29424
Related
When we have multiple parent-child grid and want to re config the grid after load call like this:
listeners: {
'afterrender': function (grid) {
var state =grid.getState();
state.columns[1].hidden= true;
grid.applyState(state);
}
}
This behaviour is even still reproducable on ExtJS 6.5.1.
For Example
https://www.sencha.com/forum/showthread.php?306941-Apply-state-after-grid-reconfigure
Here's an override I've been using to fix the hidden columns issue. I am using 6.6 so not sure if this will work in 4.4, though. Also, you may not need to suspend/resume layouts but not sure on that either.
Ext.define('MyApp.overrides.Grid', {
override: 'Ext.grid.Panel',
applyState: function () {
this.callParent(arguments);
Ext.suspendLayouts();
Ext.each(this.getColumns(), function (column) {
if (column.hidden) {
column.show();
column.hide();
}
});
Ext.resumeLayouts(true);
}
});
Well it's still an issue with applyState. When grid is having multiple hidden columns and we use applyState function it crash our grid. So we have skip the hidden property part although it's working smooth for width change , filters etc.
listeners: {
'afterrender': function (grid) {
var state =grid.getState();
state.columns[1].hidden= false;
grid.applyState(state);
grid.columns[3].hidden = true;
}
}
if you manually set hidden property of column it'll hide it.
I've posted this over on the Sencha forums, wanted to also post it here just in case:
I have a GridPanel that utilizes a PagingToolbar and a CheckboxSelectionModel. I want to keep track of selections across pages. I'm nearly there, but I'm running into issues with the PagingToolbar controls (such as next page) firing a 'selectionchange' event on the my selection model.
Here's a simplified sample of my code:
Code:
var sm = Ext.create('Ext.selection.CheckboxModel', {
listeners:{
selectionchange: function(selectionModel, selectedRecords, options){
console.log("Selection Change!!");
// CODE HERE TO KEEP TRACK OF SELECTIONS/DESELECTIONS
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
autoScroll:true,
store: store,
defaults: {
sortable:true
},
selModel: sm,
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
displayInfo: true
}],
listeners: {'beforerender' : {fn:function(){
store.load({params:params});
}}}
});
store.on('load', function() {
console.log('loading');
console.log(params);
console.log('selecting...');
var records = this.getNewRecords();
var recordsToSelect = getRecordsToSelect(records);
sm.select(recordsToSelect, true, true);
});
I assumed that I could select the records on the load event and not trigger any events.
What's happening here is that the selectionchange event is being triggered on changing the page of data and I don't want that to occur. Ideally, only user clicking would be tracked as 'selectionchange' events, not any other component's events bubbling up and triggering the event on my selection model. Looking at the source code, the only event I could see that fires on the PagingToolbar is 'change'. I was trying to follow how that is handled by the GridPanel, TablePanel, Gridview, etc, but I'm just not seeing the path of the event. Even then, I'm not sure how to suppress events from the PagingToolbar to the SelectionModel.
Thanks in advance,
Tom
I've managed to handle that. The key is to detect where page changes. Easiest solution is to set buffer for selection listener and check for Store.loading property.
Here is my implementation of selection model:
var selModel = Ext.create('Ext.selection.CheckboxModel', {
multipageSelection: {},
listeners:{
selectionchange: function(selectionModel, selectedRecords, options){
// do not change selection on page change
if (selectedRecords.length == 0 && this.store.loading == true && this.store.currentPage != this.page) {
return;
}
// remove selection on refresh
if (this.store.loading == true) {
this.multipageSelection = {};
return;
}
// remove old selection from this page
this.store.data.each(function(i) {
delete this.multipageSelection[i.id];
}, this);
// select records
Ext.each(selectedRecords, function(i) {
this.multipageSelection[i.id] = true;
}, this);
},
buffer: 5
},
restoreSelection: function() {
this.store.data.each(function(i) {
if (this.multipageSelection[i.id] == true) {
this.select(i, true, true);
}
}, this);
this.page = this.store.currentPage;
}
And additional binding to store is required:
store.on('load', grid.getSelectionModel().restoreSelection, grid.getSelectionModel());
Working sample: http://jsfiddle.net/pqVmb/
Lolo's solution is great but it seems that it doesn't work anymore with ExtJS 4.2.1.
Instead of 'selectionchange' use this:
deselect: function( selectionModel, record, index, eOpts ) {
delete this.multipageSelection[i.id];
},
select: function( selectionModel, record, index, eOpts ) {
this.multipageSelection[i.id] = true;
},
This is a solution for ExtJs5, utilizing MVVC create a local store named 'selectedObjects' in the View Model with the same model as the paged grid.
Add select and deselect listeners on the checkboxmodel. In these functions add or remove the selected or deselected record from this local store.
onCheckboxModelSelect: function(rowmodel, record, index, eOpts) {
// Add selected record to the view model store
this.getViewModel().getStore('selectedObjects').add(record);
},
onCheckboxModelDeselect: function(rowmodel, record, index, eOpts) {
// Remove selected record from the view model store
this.getViewModel().getStore('selectedObjects').remove(record);
},
On the pagingtoolbar, add a change listener to reselect previously seleted records when appear in the page.
onPagingtoolbarChange: function(pagingtoolbar, pageData, eOpts) {
// Select any records on the page that have been previously selected
var checkboxSelectionModel = this.lookupReference('grid').getSelectionModel(),
selectedObjects = this.getViewModel().getStore('selectedObjects').getRange();
// true, true params. keepselections if any and suppresses select event. Don't want infinite loop listeners.
checkboxSelectionModel.select(selectedObjects, true, true);
},
After whatever action is complete where these selections are no longer needed. Call deselectAll on the checkboxmodel and removeAll from the local store if it will not be a destroyed view. (Windows being closed, they default set to call destroy and will take care of local store data cleanup, if that is your case)
We are using fieldset in our application using extjs3.Now we are moving forward to extjs4.So beforeexpand and beforecollapse are not working in extjs4.Is there any chance to use these or else any replacement to these events.Please help me.I am searching a lot for these.
Yes, there are no such events but it's easy to create them by yourself. Here's my fieldset which extends original one and has requested events:
Ext.define('MY.fieldset', {
extend: 'Ext.form.FieldSet',
alias: 'widget.myfieldset',
initComponent: function() {
this.addEvents('beforeexpand', 'beforecollapse');
this.callParent([arguments]);
},
setExpanded: function(expanded){
var bContinue;
if (expanded)
bContinue = this.fireEvent('beforeexpand', this);
else
bContinue = this.fireEvent('beforecollapse', this);
if (bContinue !== false)
this.callParent([expanded]);
}
});
And here is working example.
How can I use Ext.tree.ViewDDPlugin's events?
I have a TreePanel that uses DDPplugin, but I'd like to know how to listen to the drop event.
This is what my code looks like:
var monPretree = Ext.create('Ext.tree.Panel',{
id : 'treepanel',
title : 'TITRE',
//width : 800,
//height : 600,
width : 500,
enableDD: true,
useArrows : true,
viewConfig : {
plugins : {
ptype: 'treeviewdragdrop',
appendOnly: true,
listeners: {
drop: function (node, data, overModel, dropPosition) {
alert('CHANGE');
},
notifyDrop: function (dragSource, event, data) {
var nodeId = data.node.id;
alert(nodeId);
},
notifyOver: function (dragSource, event, data) {
alert('over');
}
}
}
},
singleExpand : false,
store : monPrestore,
rootVisible : false,
I would like to fire drop events for example, but my code doesn't work
Thanks :)
I've got same question and found this page.
There is note in documentation, in event section:
"This event is fired through the TreeView. Add listeners to the TreeView object"
I've tryed to found method in tree.Panel class to get view, unsuccessfully. So, all you need to do, just put listners block in configuration to viewConfig section (not in plugin section):
viewConfig : {
plugins : {
ptype: 'treeviewdragdrop',
...
},
listeners: {
drop: function (node, data, overModel, dropPosition) {
alert('CHANGE');
},
}
}
},
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.tree.plugin.TreeViewDragDrop-event-drop
Take a look at the doc :
beforeinsert( Tree tree, Node parent, Node node, Node refNode, Object options )
Fires before a new child is inserted in a node in this tree, return false to cancel the insert. ...
As an addition to Anton's correct answer above: The code below shows how to "connect from the outside" to drop events, for example from a Controller etc:
// Drag & Drop on the TreePanel
var ganttTreeView = ganttTreePanel.getView();
ganttTreeView.on({
'drop': me.onDrop,
'scope': this
});;
You can also catch the drop event by overriding dropConfig inside a TreeGrid or TreePanel. Here is an example how I did.
var myTree = new Tree.TreePanel({
id: 'treepanel',
title: 'My Title',
enableDD: true,
ddGroup: 'GridDD',
dataUrl: 'yourMethodURLForJSONData',
dropConfig: {
dropAllowed: true,
ddGroup: "GridDD",
notifyDrop: function(source, e, data) {
alert("A node/leaf is dropped");
//If you want few more details
if (data.grid) {
var node = data.selections[0].data;
alert("This is a node dropped from a Grid.");
} else {
var node = data["node"];
alert("This is a node dropped from a Tree.");
}
}
}
});
You can also do the same for Ext.ux.tree.TreeGrid. Hope It will help.
i want to change a tooltip's position to show it upon a button. I tried the method below as mentioned in ExtJs's forum. It doesn't work, i can't override the getTargetXY method, the tooltip is shown always in the same position. Do you have any solution ?
this.desktopButton = new Ext.Button({
icon: "arrow_in.png",
scope: this,
handler: this.desktopButtonHandler,
tooltip: new Ext.ToolTip({
text: 'Message',
getTargetXY: function () {
return [100, 100];
}
})
});
Ext elements can only be passed configuration options as specified in the documentation; getTargetXY is not one of those options.
If you want to override that method, you have two choices:
Override all Ext Tooltips to use your new function
Extend the existing Tooltip class to support overriding that method
I would not recommend overriding the method, as that could have other consequences. I will, however, explain how to do both.
To override the tooltip:
Ext.override(Ext.Tooltip, {
getTargetXY: function() {
return [100, 100]
}
});
To extend the tooltip:
MyToolTip = Ext.Extend(Ext.Tooltip, {
constructor: function(config) {
var config = config || {};
if (config.getTargetXY) {
this.getTargetXY = config.getTargetXY;
}
MyToolTip.superclass.constructor.call(this, config);
}
});
Note that setting 'targetXY' may prove unhelpful, as Ext JS may override this setting (depending on the view size).
Overriding the "showAt" method can prevent this:
showAt:function() {
var xy = [this.getTargetXY()[0],this.getTargetXY()[1]-this.height]
MyTooltip.superclass.showAt.call(this, xy);
}