ExtJS 7 - Column filter issue with locked column - extjs

I encountered this bug where the column filter is incorrect if the grid has a locked column
Here's the fiddle: sencha fillde
Steps to reproduce:
(Do not apply any filter)
Open the "Email" column menu
Open "Name" column menu (this is the locked column)
Open "Phone" column menu (notice that the filter menu is incorrect, it is showing the filter for "Email" column).
For grid that has no 'locked' columns the filter menu is working fine, thanks for anyone who can help!

Okay, this one was a bit tricky. It turns out that for a locked grid, the Ext.grid.filters.Filters:onMenuCreate gets hit twice... one for each side of the grid's menu that shows. The problem is that in the onMenuCreate, the framework doesn't account for the 2 menus. It only cares about the last menu that gets created and destroys the previous menu's listeners. In onMenuBeforeShow, the framework does account for each side of the grid, so I extended this idea into an override. I would encourage you to create a Sencha Support ticket for this, and if you don't have access, let me know, so I can submit one. Fiddle here.
Ext.override(Ext.grid.filters.Filters, {
onMenuCreate: function (headerCt, menu) {
var me = this;
// TODO: OLD BAD CODE... this would destroy the first menu's listeners
// if (me.headerMenuListeners) {
// Ext.destroy(me.headerMenuListeners);
// me.headerMenuListeners = null;
// }
// me.headerMenuListeners = menu.on({
// beforeshow: me.onMenuBeforeShow,
// destroyable: true,
// scope: me
// });
// Just like in the onMenuBeforeShow, we need to create a hash of our menus
// and their listeners... if we don't, we remove the 1st menu's listeners
// when the 2nd menu is created
if (!me.headerMenuListeners) {
me.headerMenuListeners = {};
}
var parentTableId = headerCt.ownerCt.id;
var menuListener = me.headerMenuListeners[parentTableId];
if (menuListener) {
Ext.destroy(menuListener);
me.headerMenuListeners[parentTableId] = null;
}
me.headerMenuListeners[parentTableId] = menu.on({
beforeshow: me.onMenuBeforeShow,
destroyable: true,
scope: me
});
},
destroy: function () {
var me = this,
filterMenuItem = me.filterMenuItem,
item;
// TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
var headerMenuListeners = this.headerMenuListeners;
Ext.destroy(me.headerCtListeners, me.gridListeners);
me.bindStore(null);
me.sep = Ext.destroy(me.sep);
for (item in filterMenuItem) {
filterMenuItem[item].destroy();
}
// TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
for (item in headerMenuListeners) {
headerMenuListeners[item].destroy();
}
this.callParent();
}
});

Related

ExtJS6 DragZone on Grid with CheckBox Model

I have a grid which is enabled with Ext.dd.DragZone. I am dragging records from the grid and dropping them on various nodes in a tree panel. Single record drops work great; however, I am unable to successfully drag multiple records to a tree node...only one record gets processed. The DragZone is instantiated on the render of the view by the following function:
renderDD: function(view){
grid = view.up('gridpanel');
grid.dragZone = Ext.create('Ext.dd.DragZone',view.el,{
onBeforeDrag: function(data,e){
return data.messagedata.foldertype==2 ? false : true;
},
getDragData: function(e){
var sourceEl = e.getTarget(view.itemSelector,10),d;
if(sourceEl){
d = sourceEl.cloneNode(true);
d.id = Ext.id();
return(view.dragData = {
sourceEl: sourceEl,
repairXY: Ext.fly(sourceEl).data,
ddel: d,
messagedata:view.getRecord(sourceEl).data
});
}
},
getRepairXY: function(){
return this.dragData.repairXY;
}
});
},
...
Can any one help me on dragging multiple records using DragZone and DropZone (not the grid plugins). Thank you kindly.
I would most likely do something like this Fiddle if you can't use the plugins. You can customize how you want the drag to look with your own HTML. I'm not really sure if this is the proper way to do it, but it was my first stab at it. Hopefully it helps you figure out how you want to tackle this.
The reason your code isn't working is because you're only getting a single record. Instead, I'm making use of the getSelection method provided by the grid class, which returns all of the selected items I've selected in the grid because I've created a rowmodel selection model with mode MULTI.
getDragData: function (event, b, c) {
var selection = view.getSelection();
var sourceEl = document.createElement('div');
sourceEl.innerHTML = 'blah';
if (selection) {
var d = sourceEl.cloneNode(true);
d.id = Ext.id();
return {
sourceEl: sourceEl,
repairXY: Ext.fly(sourceEl).getXY(),
ddel: d,
records: selection
};
}
},

working on select but not on blur - EXTJS

I am newbie to ExtJS I have the following lines of code that is working fine on select event and now I am planning to add on blur event too.
autoResolve.on("select" || "blur", function (component, record, index) {
var fieldSet = utils.getComponentFromMngr(component.id.split("~")[0]);
if(autoResolveData.CURRSEL){ //Set previous selection property
var xmlElem = fieldSet.DomainXML.documentElement.childNodes[1];
xmlElem.setAttribute("PR_DOMAINTYPE",autoResolveData.FILL_SUBTYP);
xmlElem.setAttribute("PR_DOMAINID", record.get("ITEMID"));
xmlElem.setAttribute("PR_DOMAINVALUE", record.data.TITLE);
fieldSet.DomainObj.push({PRDomainType:autoResolveData.FILL_SUBTYP,PRDomainID:record.get("ITEMID"),PRDomainValue:record.data.TITLE});
}
it is still working fine on select event but not on blur event where am I going wrong please suggest
"select" || "blur" will return select, as you can find out if you type the following in browser console:
console.log("select" || "blur");
Furthermore, "blur" event does not have record as the second parameter. You would have to look how to get record and call the function with a valid record parameter.
What you want to achieve is roughly the following:
var myFunction = function (component, record, index) {
var fieldSet = utils.getComponentFromMngr(component.id.split("~")[0]);
if(autoResolveData.CURRSEL){ //Set previous selection property
var xmlElem = fieldSet.DomainXML.documentElement.childNodes[1];
xmlElem.setAttribute("PR_DOMAINTYPE",autoResolveData.FILL_SUBTYP);
xmlElem.setAttribute("PR_DOMAINID", record.get("ITEMID"));
xmlElem.setAttribute("PR_DOMAINVALUE", record.data.TITLE);
fieldSet.DomainObj.push({PRDomainType:autoResolveData.FILL_SUBTYP,PRDomainID:record.get("ITEMID"),PRDomainValue:record.data.TITLE});
}
};
autoResolve.on({
select:myFunction,
blur:function(component) {
var record = ... // your special magic here
return myFunction(component,record);
}
});

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

EXTJS 4: Adding listeners to elements not consistent

I'm working with an EXTJS 4 dataview and having inconsistent results when adding listeners to html elements (links) in each data node. I have placed the code in the load listener on the store that is tied to the dataview. It appears to work on the first load but subsequent loads get worse as it begins missing some elements. Each time a call store.reload() it gets worse.
I have verified in firebug that the html element ID's are rendering properly but for some reason when I reload the store it begins to miss some elements at first, then all elements. Code for the load listener below:
listeners: {
load: function(store, records, successful, options){
var nodes = records;
for (i=0, len = nodes.length; i < len;i++){
var id = nodes[i].data.id;
var addtocartel = Ext.get('img-cart-'+id);
var viewel = Ext.get('img-view-'+id);
//Setting hidden class for nonimage items
switch (nodes[i].data.type) {
case 'image' :
viewel.addCls('imgprf');
addtocartel.addCls('cartprf');
break;
default :
viewel.addCls('sc_hidden');
addtocartel.addCls('sc_hidden');
viewel.hide();
addtocartel.hide();
break;
}
if(addtocartel !== null){
addtocartel.itemid = id;
addtocartel.on('click', function(e,t){
var el = Ext.get(t);
var imgrec = imagestore.getById(el.itemid);
e.stopEvent();
prfproductwindow.show();
});
}
if(viewel !== null){
viewel.itemid = id;
viewel.on('click', function(e,t){
var el = Ext.get(t);
var imgrec = imagestore.getById(el.itemid);
});
}
}
}
}
Refreshes to the grid view can happen without any sort of load occurring. When the grid view refreshes it wipes out the existing html elements and creates new ones, so any listeners you had attached to those elements will be useless.
You should look into adding a click listener to your entire grid and using a delegate to listen for clicks on specific html elements within the view. This will allow you to add a single listener once that will always work no matter how many times the elements within the view are rerendered.
grid.getView().getEl().on('click', function(evt, target) {
console.log('clicked on ' + target);
}, {delegate: '.my-css-selector-for-some-element'});
The click handler will only be fired for clicks on elements that match the delegate selector.
Also, the logic where you are adding css classes based on the record's type should be done in the renderer (if you have a grid) or handled by the data view's template.

how to reload gird data after add new data in to the store

I have two grids; I call them child and parent grid. When I add a new row(data) into the parent grid, I want to reload the parent grid. I was trying to edit it using the afteredit function in the code. If I uncomment out line number 2 in the alert, that works fine. But with out the alert, the newly added row is hidden. I don't understand what's going wrong in my code. Please can anyone tell me what to do after I add the new row in to my grid and how to reload the grid immediately?
this my afteredit function
afteredit : function (roweditor, changes, record, rowIndex)
{ //alert('alert me');
if (!roweditor.initialized) {
roweditor.initFields();
}
var fields = roweditor.items.items;
// Disable key fields if its not a new row
Ext.each(fields, function (field, i) {
field.setReadOnly(false);
field.removeClass('x-item-disabled');
});
this.grid.getSelectionModel().selectRow(0);
this.grid.getView().refresh();
},
xt.ux.grid.woerp =
{
configRowEditor:
{
saveText: "Save",
cancelText: "Cancel",
commitChangesText: WOERP.constants.gridCommitChanges,
errorText: 'Errors',
listeners:
{
beforeedit: WOERP.grid.handler.beforeedit,
validateedit: WOERP.grid.handler.validateedit,
canceledit: WOERP.grid.handler.canceledit,
afteredit: WOERP.grid.handler.afteredit,
aftershow: WOERP.grid.handler.aftershow,
move: WOERP.grid.handler.resize,
hide: function (p)
{
var mainBody = this.grid.getView().mainBody;
if (typeof mainBody != 'undefined')
{
var lastRow = Ext.fly(this.grid.getView().getRow(this.grid.getStore().getCount() - 1));
if (lastRow != null)
{
mainBody.setHeight(lastRow.getBottom() - mainBody.getTop(),
{
callback: function ()
{
mainBody.setHeight('auto');
}
});
}
}
},
afterlayout: WOERP.grid.handler.resize
}
},
AFAIK RowEditor is a plugin for GridPanel which changes underlying data which comes from store. Usually updates are also made by store. If you want to know when data is saved, you should attach event handler to store. Example:
grid.getStore().on('save', function(){ [...] });
Finally i found solution. When i add reload function in to the afteredit method that will be hide newly added row. So Grid reload After commit data in to that data grid store work well for me. Anyway thanks lot all the people who try to help
this my code look like
record.commit();
grid.getView().refresh();
I think there exist a Save button after editing grid.
So in the handler of Save you can catch the event
or using
Ext.getCmp('your_saveButtonId').on('click', function(component, e) {
// Here they will be checking for modified records and sending them to backend to save.
// So here also you can catch save event
}

Resources