Applying loadMask() to only grid pannel in extjs is not working - extjs

I want to apply load mask to only my grid pannel using id of it,
var myMask = new Ext.LoadMask({msg:"Please wait...",target:Ext.ComponentQuery.query('#grid')[0]});
myMask.show();
But this doesn't seems to work.The same code is working for tab pannel. Please suggest the necessary changes in order to achieve load mask only for grid pannel.
//View code
Ext.define("DummyApp.view.grid.GenericGrid",{
extend: "Ext.panel.Panel",
requires: ['DummyApp.view.toolBar','DummyApp.view.formPanel','Ext.state.*','Ext.data.*'],
controller: "genericGrid",
alias:"widget.genericgrid",
initComponent: function(){
Ext.apply(this, {
items: [this.createToolbar(),this.createGrid()]
});
this.callParent(arguments);
},
createToolbar: function(){
this.toolbar = Ext.create('DummyApp.view.toolBar');
return this.toolbar;
},
createGrid: function(){
this.grid = Ext.create('Ext.grid.Panel',{
itemId: 'batchGrid',
columnLines : true,
selType: 'cellmodel',
autoScroll :true,
maxHeight:535,
stateId: 'GridPanel',
loadMask: true,
stateful: true,
bind:{
store:'{genericGrid}'
}
});
return this.grid;
}
//Controller code
renderData: function(genericGrid) {
var store = Ext.create("DummyApp.store.GenericGrid"),
gridId = genericGrid.up().gridId,
serviceInput = Util.createServiceResponse(gridId);
var myMask = new Ext.LoadMask({msg:"Please wait...",target: Ext.ComponentQuery.query('#grid')[0]});
myMask.show();
Ext.Ajax.request({
url: Util.localGridService,
method: 'POST',
headers: Util.createRequestHeaders(),
jsonData: {
getConfigurationAndDataRequestType: serviceInput
},
success: function(conn, response, options, eOpts) {
myMask.hide();
var data = Util.decodeJSON(conn.responseText);
store.setData(Util.formatGridData(data));
genericGrid.reconfigure(store, Util.formatGridMetaData(data));
},
failure: function(conn, response, options, eOpts) {
myMask.hide();
Util.showErrorMsg(conn.responseText);
},
scope: this
});
store.load();
}

Look at this, in your code grid have itemId is "batchGrid"(find by "#batchGrid"), your grid panel have alias is "genericgrid"(find by "genericgrid" because it is alias of component). Then just correct it, replace your itemId on correct name, but better for this using needed component for target
var myMask = new Ext.LoadMask({msg:"Please wait...",target: Ext.ComponentQuery.query('#batchGrid')[0]});
better
renderData: function(genericGrid) {
var store = Ext.create("DummyApp.store.GenericGrid"),
grid = genericGrid.down('#batchGrid') // get grid
...
var myMask = new Ext.LoadMask({msg:"Please wait...", target: grid /*or genericGrid for gridpanel*/ });
Fiddle

Related

Filter in grid header extjs 6

How to create a filter in the grid headers?
I found this snippet: https://stackoverflow.com/a/22015160/5775332 and updated to compatibility with 6th version:
Ext.define('Fiddle.view.SearchTrigger', {
extend: 'Ext.form.field.Text',
alias: 'widget.searchtrigger',
requires: [
'Ext.form.trigger.Trigger'
],
defaultListenerScope: true,
triggers: {
search: {
handler: function(field, trigger, e) {
this.setFilter(this.up().dataIndex, this.getValue());
},
cls: 'x-form-search-trigger'
},
clear: {
handler: function(field, trigger, e) {
this.setValue('');
if(!this.autoSearch) this.setFilter(this.up().dataIndex, '');
},
cls: 'x-form-clear-trigger'
}
},
listeners: {
render: 'onTextfieldRender',
change: 'onTextfieldChange'
},
onTextfieldRender: function(component, eOpts) {
var me = this;
me.ownerCt.on('resize', function(){
me.setWidth(this.getEl().getWidth());
});
},
onTextfieldChange: function(field, newValue, oldValue, eOpts) {
if(this.autoSearch) this.setFilter(this.up().dataIndex, this.getValue());
},
setFilter: function(filterId, value) {
var store = this.up('grid').getStore();
if(value){
store.removeFilter(filterId, false);
var filter = {id: filterId, property: filterId, value: value};
if(this.anyMatch) filter.anyMatch = this.anyMatch;
if(this.caseSensitive) filter.caseSensitive = this.caseSensitive;
if(this.exactMatch) filter.exactMatch = this.exactMatch;
if(this.operator) filter.operator = this.operator;
console.log(this.anyMatch, filter);
store.addFilter(filter);
} else {
store.filters.removeAtKey(filterId);
store.reload();
}
}
});
The most difficult place - creation items with widget in column.
I cant reproduce it in Sencha Fiddle. How to do it?
First login to Sencha Fiddle using the Sencha Forum credentials. After this, copy-paste your code and save it. The updated url that you get after saving will be sharable. Please refer here for docs on Sencha Fiddle.
Fixed code: https://fiddle.sencha.com/#view/editor&fiddle/2820

ExtJS 5.x How to change grid view (viewConfig) after store load?

I have a store in ViewModel like:
Ext.define('MyApp.page.PageModel', {
extend: 'Ext.app.ViewModel',
//...
stores: {
Posts: {
model: //...
}
}
});
And a grid like:
Ext.define('MyApp.page.MainView', {
extend: 'Ext.panel.Panel',
//...
initComponent: function () {
var me = this;
//...
me.items = [
{
xtype: 'grid',
bind: {
store: '{Posts}'
},
columns: [ /* ... */ ],
viewConfig: {
getRowClass: function (record) {
//...
}
}
}
];
me.callParent(arguments);
}
});
How can I change grid view AFTER store load (in my case)?
I tried to use mon and addManagedListener methods in grid events (beforerender and viewready) and I tried to use on and addListener methods to store inside those grid events, but this solution is not working.
Does someone have any ideas?
I'm using override for Ext.view.AbstractView, just to clear emptyEl and viewEl before store load event
store.on('beforeload', function() {
me.clearEmptyEl();
me.clearViewEl();
});
Here is my complete override
Ext.define('Ext.overrides.view.AbstractView', {
override: 'Ext.view.AbstractView',
onBindStore: function(store, initial, propName) {
var me = this;
me.setMaskBind(store);
// After the oldStore (.store) has been unbound/bound,
// do the same for the old data source (.dataSource).
if (!initial && propName === 'store') {
// Block any refresh, since this means we're binding the store, which will kick off
// a refresh.
me.preventRefresh = true;
// Ensure we have the this.store reference set correctly.
me.store = store;
me.bindStore(store, false, 'dataSource');
me.preventRefresh = false;
}
store.on('beforeload', function() {
me.clearEmptyEl();
me.clearViewEl();
});
}
});
In ExtJS 6, a function setEmptyText is available on the grid that will do this for you:
initComponent: function () {
var me = this;
//...
me.callParent(arguments);
me.getStore().on('load', function() {
me.setEmptyText(...);
})
}
In ExtJS 5, you have to do on your own:
me.getStore().on('load', function() {
var emptyText = 'Test empty text';
me.getView().emptyText = '<div class="' + me.emptyCls + '">' + emptyText + '</div>';
me.getView().refresh();
})
Relevant fiddle, will load its store 3 seconds after rendering.

ExtJs - Filter a grid with a search field in the column header

In ExtJs, there are many options to filter a grid. There are two nice examples in the documentation, like referenced in this question.
Remote filtering
Local filtering
However, having the filter hidden in the default dropdown menu of Ext.ux.grid.FiltersFeature looks really awkward for me. A good ergonomic choice would to create search fields in the column headers, like #Ctacus shows in his question.
How can this be achieved ?
After quite much research through the sparse documentation, and thanks to great questions and answers in SO, I came up with a simple class, that adds this functionality and and allows for configurations.
It looks like this:
You add this field in your grid like this:
Ext.define('Sandbox.view.OwnersGrid', {
extend: 'Ext.grid.Panel',
requires: ['Sandbox.view.SearchTrigger'],
alias: 'widget.ownersGrid',
store: 'Owners',
columns: [{
dataIndex: 'id',
width: 50,
text: 'ID'
}, {
dataIndex: 'name',
text: 'Name',
items:[{
xtype: 'searchtrigger',
autoSearch: true
}]
},
The following configs are possible, and work like described in the doc for Ext.util.Filter:
anyMatch
caseSensitive
exactMatch
operator
additionnaly you can use autoSearch. If true, the filter searches as you type, if false or not set, one has to click on the search icon to apply the filter.
ExtJs 5 / 6 Source:
Ext.define('Sandbox.view.SearchTrigger', {
extend: 'Ext.form.field.Text',
alias: 'widget.searchtrigger',
triggers:{
search: {
cls: 'x-form-search-trigger',
handler: function() {
this.setFilter(this.up().dataIndex, this.getValue())
}
},
clear: {
cls: 'x-form-clear-trigger',
handler: function() {
this.setValue('')
if(!this.autoSearch) this.setFilter(this.up().dataIndex, '')
}
}
},
setFilter: function(filterId, value){
var store = this.up('grid').getStore();
if(value){
store.removeFilter(filterId, false)
var filter = {id: filterId, property: filterId, value: value};
if(this.anyMatch) filter.anyMatch = this.anyMatch
if(this.caseSensitive) filter.caseSensitive = this.caseSensitive
if(this.exactMatch) filter.exactMatch = this.exactMatch
if(this.operator) filter.operator = this.operator
console.log(this.anyMatch, filter)
store.addFilter(filter)
} else {
store.filters.removeAtKey(filterId)
store.reload()
}
},
listeners: {
render: function(){
var me = this;
me.ownerCt.on('resize', function(){
me.setWidth(this.getEl().getWidth())
})
},
change: function() {
if(this.autoSearch) this.setFilter(this.up().dataIndex, this.getValue())
}
}
})
For ExtJs 6.2.0, the following bug and its workaround is relevant to this, else the column cannot be flexed.
ExtJs 4 Source:
Ext.define('Sandbox.view.SearchTrigger', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.searchtrigger',
triggerCls: 'x-form-clear-trigger',
trigger2Cls: 'x-form-search-trigger',
onTriggerClick: function() {
this.setValue('')
this.setFilter(this.up().dataIndex, '')
},
onTrigger2Click: function() {
this.setFilter(this.up().dataIndex, this.getValue())
},
setFilter: function(filterId, value){
var store = this.up('grid').getStore();
if(value){
store.removeFilter(filterId, false)
var filter = {id: filterId, property: filterId, value: value};
if(this.anyMatch) filter.anyMatch = this.anyMatch
if(this.caseSensitive) filter.caseSensitive = this.caseSensitive
if(this.exactMatch) filter.exactMatch = this.exactMatch
if(this.operator) filter.operator = this.operator
console.log(this.anyMatch, filter)
store.addFilter(filter)
} else {
store.filters.removeAtKey(filterId)
store.reload()
}
},
listeners: {
render: function(){
var me = this;
me.ownerCt.on('resize', function(){
me.setWidth(this.getEl().getWidth())
})
},
change: function() {
if(this.autoSearch) this.setFilter(this.up().dataIndex, this.getValue())
}
}
})

ExtJS 3 multiple stateful grids (but with different stateIds)

I have my grid, which overwrites Ext.grid.GridPanel
I use this grid in 2 places on my site. I generate 2 different stateIds for them:
constructor:
TasksGrid.superclass.constructor.call(this, {
id: genId,
cls: 'tasks-grid',
border: false,
loadMask: {msg: 'Loading...'},
sm: sm,
stateful: true,
stateId: 'tasks-grid'+(config.booClientTab ? '-clients-tab' : ''), // depending on config.booClientTab I setup one or other stateId
...
this code I call in 2 places on site to create 2 grids:
this.TasksGrid = new TasksGrid(this, {
region: 'west',
split: true,
width: tasksGridWidth ? tasksGridWidth : defaultWidth,
booShowToolbar: true,
booClientTab: !empty(config.clientId) // if true, 1 stateId will be setup, false - other
});
But, when I test, state is applied only to first of 2 generated grids!! I checked cookies: seems, that all works fine: 2 cookies with 2 different names are created. But... State applies only to first call of "this.TasksGrid = new TasksGrid"!!!
ExtJS version: 3.0
Any thoughts?
I had the same problem. State can be applied to the component only during initialization not after initialization. Therefore it works for the first time but not after. Luckily you are using EextJs 3 and following piece of code worked for me in ExtJS 3 but not in 4. Basically when you apply new/other state to the grid just call
MyGrid = Ext.extend(Ext.grid.GridPanel,
{
/* #private */
constructor: function(config)
{
MyGrid.superclass.constructor.call(this, config);
},
initComponent: function()
{
var cfg =
{
border: true,
bodyBorder: false,
stateful: true,
stateId: 'grid',
tbar:
[{
text: 'View name'
},{
xtype: 'combo',
width: 80,
typeAhead: true,
triggerAction: 'all',
mode: 'local',
forceSelection: true,
hiddenName: 'stateId',
selectOnFocus:true,
displayField:'name',
ref: '../stateCombo',
valueField: 'id',
listeners:
{
scope: this,
change: function(combo, newValue, oldValue)
{
newValue = parseInt(newValue, 10); var grd = this;
grd.el.mask('Applying the view please wait');
var data = combo.store.data.items;
Ext.each(data, function(d)
{
d.data.id = parseInt(d.data.id, 10);
if(d.data.id === newValue)
{
Ext.util.Cookies.set('reportStateName', d.data.machineName);
grd.applyState(MyStateProvider.decodeState(d.data.value));
var conf = grd.getColumnModel().config;
grd.getColumnModel().setConfig(conf);
grd.doLayout();
grd.getView().updateAllColumnWidths();
grd.getView().refresh(true);
return;
}
});
grd.el.unmask();
grd = null;
}
},
store: new Ext.data.JsonStore
({
fields:
[{
name: 'id',
type: 'int'
}],
proxy : new Ext.data.HttpProxy
({
method: 'GET',
url: BASEURL + 'getsavedstate'
}),
idProperty: 'id'
})
}]
};
//we use applyIf for configuration attributes that should be left configurable
Ext.applyIf(this, cfg);
//ensure that any extra configurations that are set in initComponent method are applied to initialConfig:
Ext.applyIf(this.initialConfig, cfg);
/*
* Properties specified here are safe/protected from being overridden
* by an instance, so any 'private' default properties might be specified here.
*/
//some attributes we may want to keep unaltered, so we use Ext.apply non-alterable configurables
cfg =
{
sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
stripeRows: true,
loadMask: true
};
Ext.apply(this, cfg);
//need this to work sometimes:
Ext.apply(this.initialConfig, cfg);
MyGrid.superclass.initComponent.apply(this, arguments);
this.on
({
afterrender: function(grid)
{
var grd = this;
this.stateCombo.getStore().load
({
callback: function(data, options, success)
{
grd.saveAsStateBtn.enable();
var applied = false;
var setStateValue = Ext.util.Cookies.get('reportStateName');
Ext.each(data, function(d)
{
//meaning no cookie was set so first time.
if(setStateValue === null)
{
if(d.data.machineName === 'default')
{
if(d.data.value !== '')
{
grd.applyState(MyStateProvider.decodeState(d.data.value));
applied = true;
grd.stateCombo.setValue(d.data.id);
return;
}
applied = true;
grd.stateCombo.setValue(d.data.id);//Here value should be fetched from cookie
return;
}
}
else//Cookie was set
{
if(d.data.machineName === setStateValue)
{
if(d.data.value !== '')
{
var s = MyStateProvider.decodeState(d.data.value);
grd.applyState(s);
applied = true;
grd.stateCombo.setValue(d.data.id);//Here value should be fetched from cookie
return;
}
else
{
return;
}
}
}
});
//grd.doLayout();
if(data.length !== 0)
{
grd.stateCombo.enable();
grd.saveStateBtn.enable();
}
var conf = grd.getColumnModel().config;
grd.getColumnModel().setConfig(conf);
grd.doLayout();
grd.getView().updateAllColumnWidths();
grd.getView().refresh(true);
grd.doLayout();
grd.el.unmask();
}
});
this.el.mask('Applying the saved view please wait');
},
scope: this
});
},
onRender: function (container, position)
{
MyGrid.superclass.onRender.apply(this, arguments);
var el = this.el;
var grd = this;
this.saveStateWindow = new MySaveStateWindow
({
grid: grd,
renderTo: el
});
},
// template method
/* #private */
initEvents: function()
{
MyGrid.superclass.initEvents.apply(this, arguments);
},
afterRender: function()
{
MyGrid.superclass.afterRender.apply(this, arguments);
},
// template method
/* #private */
beforeDestroy: function()
{
//Call parent
MyGrid.superclass.beforeDestroy.apply(this, arguments);
},
onDestroy: function()
{
this.saveStateWindow.destroy();
MyGrid.superclass.onDestroy.apply(this, arguments);
}
});

Asscociating a store with Ext.menu.Menu

I am new to extjs.I want to associate a store on selecting a menu item from Ext.menu.Menu. I am using extjs 4.1.0. I searched on the net even went through sencha doc but I couldn't find any way to achieve this.
Is there some way to achieve it?
Thanks in advance.
I'm using a menu with a store in a project. Here's an example:
Ext.define("Ext.ux.menu.DynamicMenu", {
extend: "Ext.menu.Menu",
alias: 'widget.dynamicmenu',
loaded: false,
loadMsg: 'Loading...',
store: undefined,
icon: '',
constructor: function (config) {
var me = this;
Ext.apply(me, config);
me.callParent();
},
initComponent: function () {
var me = this;
me.callParent(arguments);
me.on('show', me.onMenuLoad, me);
listeners = {
scope: me,
load: me.onLoad,
beforeload: me.onBeforeLoad
};
me.mon(me.store, listeners);
},
onMenuLoad: function () { var me = this; if (!me.store.loaded) me.store.load(); },
onBeforeLoad: function (store) { this.updateMenuItems(false); },
onLoad: function (store, records) { this.updateMenuItems(true, records); },
updateMenuItems: function (loadedState, records) {
var me = this;
me.removeAll();
if (loadedState) {
me.setLoading(false, false);
Ext.Array.each(records, function (record, index, array) {
me.add({
text: record.get('DisplayName'),
data: record,
icon: me.icon
});
});
me.store.loaded = true;
}
else {
me.add({ width: 75, height: 40 });
me.setLoading(me.loadMsg, false);
}
me.loaded = loadedState;
}
});
I found this one on the sencha forums if IIRC, but can't find the link anymore. I made some tweaks for icons etc, ...
On the Ext.Array.each(records, ....
You'll need to define your own logic, It's depending on your model. My model has a DisplayName which I use to show as text. I also stock my record in a data property I made in the menu item. You're completely free there.
Good luck!

Resources