I have this very basic example where I use a memoryproxy and pagingmemory toolbar to paginate through data (ideally).
This is extjs working with meteor which sends data directly without the need of a res/ajax/jsonp proxy so I must use memory since the data is already in the client long before extjs has even managed to render it's views.
My problem is that I cannot make the pagination to show a real overview of what's in the store. The refresh is not working and the paginate icons are dead since the pagination sees no items in the store after I load them.
I have a working code example up on jsfiddle: http://jsfiddle.net/rXsVG/5/
Full code example:
Ext.onReady(function(){
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
]
});
var store = new Ext.data.Store({
model: 'User',
autoLoad: true,
proxy: {
type: 'pagingmemory',
reader: {
type: 'json'
}
}
});
Ext.create('Ext.grid.Panel', {
height: 500,
width: '100%',
renderTo: 'example-grid',
store: store,
columns: [{
header: 'Name',
dataIndex: 'name',
flex: 1
}],
bbar: {
xtype: 'pagingtoolbar',
pageSize: 10,
store: store,
displayInfo: true
},
listeners: {
afterrender: function(grid, evt) {
console.log('Loading data');
var data = [];
for(var i = 1; i < 20; i++) {
data.push({
id: i,
name: 'Ed Spencer '+i
});
}
// Simulate a really busy server call
setTimeout(function(){
grid.getStore().loadData(data);
}, 500);
}
}
});
});
Also if you hit refresh on the paging toolbar all data will be gone. Any ideas?
Related
I use ExtJS 6.0.0, REST proxy with TreeStore. So when i remove some records from the store store.remove(records), then try to sync changes with server and call store.sync() and nothing happend! A callback function of sync not called.
url: '/admin/pages', return simple nested data in proper format.
View and update operations work well.
I made a simple code fragment just to illustrate the issue:
Ext.define('Pages', {
extend: 'Ext.data.TreeModel',
fields: [
{name: 'id', type: 'int'},
{name: 'parent_id', type: 'int'},
{name: 'title', type: 'string'}
]
});
Ext.onReady(function() {
var store = Ext.create('Ext.data.TreeStore', {
model: 'Pages',
proxy: {
type: 'rest',
url: '/admin/pages',
}
});
var tree = Ext.create('Ext.tree.Panel', {
width: 500,
height: 300,
renderTo: Ext.getBody(),
rootVisible: false,
store: store,
multiSelect: true,
columns: [{
xtype: 'treecolumn',
text: 'title',
sortable: true,
dataIndex: 'title'
}],
tbar: [
{
text: 'Delete',
handler: function () {
var records = tree.getSelection();
store.remove(records); // remove nodes from tree
store.sync(); // do nothing!! WHY?
},
}
]
});
If the store is configured as autoSync:true the record's endEdit method will have already internally caused a save to execute on the store. We only need to save manually when autoSync is false, otherwise, we'll create duplicate transactions.
You need to the call the store.load() after you do the syncing using store.sync()
I have a tab panel, and I perform a server request in it's initComponent method to add tabs according to the result. This process can take a long time, and I would like to display a progress bar during the begining of initComponent, till the end (before the callParent call method for example).
Is it possible to achieve this behaviour ?
Thanks a lot !
You can use a LoadMask on any pretty much any component, here is an example, there is also a fiddle:
Ext.application({
name: 'Fiddle',
launch: function() {
var store = Ext.create('Ext.data.JsonStore', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone'],
autoLoad: true,
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: 'characters'
}
},
listeners: {
load: function() {
console.log(this);
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: store,
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
var myMask = new Ext.LoadMask(grid, {msg:"Please wait..."});
myMask.show();
var timeout = setTimeout(function() {
myMask.hide();
}, 5000);
}
});
I've added a setTimeout to replicate a long loading request, you do not need to use this.
You do not need to rely on "callParent" method. You have two options:
Make your server request synchronously. (by setting async:false for your ext.ajax call or for the related operation) It causes your code to be waited till the response comes.it blocks UI interaction but makes you sure having response immediately in line after server call
Another way is calling this.setLoading(true) before calling ajax call and setting this.setLoading(false) in your ajax/operation callback method. Note that this should refer to your main component. So it is bettor to save it in a variable at initComponent first line. For example by a line like var me= this;. After that refer to current main component bymeinstead ofthis`
var progressBar = Ext.create('Ext.ProgressBar');
progressBar.wait({
interval: 1000,
duration: 10000,
increment: 10,
text: 'Adding tabs...',
scope: this,
fn: function() {
var tabPanel = Ext.create('Ext.tab.Panel');
me.add(tabPanel);
tabPanel.add({
xtype: 'panel',
title: 'Main tab'
});
tabPanel.add({
xtype: 'panel',
title: 'Chunk'
});
tabPanel.add({
xtype: 'panel',
title: 'My girl'
});
progressBar.hide();
}
});
Fiddle
I have a large dataset (over 80k records). So I am trying to implement buffer but I couldn't get it work. If I include buffered configuration I am getting error object doesn't support this property. When I remove it, works ok but of course it takes forever to load the data.
Here is my code
Ext.Loader.setConfig({
enabled: true,
disableCaching: false
});
Ext.require(['Ext.data.*', 'Ext.grid.*',
'Ext.grid.plugin.BufferedRenderer', 'Ext.ux.grid.FiltersFeature']);
Ext.define('Borrower', {
extend: 'Ext.data.Model',
fields: [{
name: 'Name',
type: 'string'
}, {
name: 'Num',
type:
'string'
}]
});
Ext.onReady(function () {
var store = Ext.create('Ext.data.Store', {
autoLoad: false,
model: 'Borrower',
pageSize: 100,
buffered: true, // getting error object doestn support this property in extjs-all-debug.js
proxy: {
type: 'rest',
url: 'borrBuff.xsp/byName',
reader: {
type: 'json',
root: 'items'
}
}
});
var filters = {
ftype: 'filters',
encode: false,
local: true
};
var grid = Ext.create('Ext.grid.Panel', {
id: 'testgrid',
store: store,
features: [filters],
plugins: 'bufferedrenderer',
columns: [{
text: 'Borr Name',
dataIndex: 'Name',
filterable: true
}, {
text: 'Number',
dataIndex: 'Num'
}]
});
})
Opening the grid in a window on button click
var grid = Ext.getCmp('testgrid');
var win = Ext.create('Ext.Window', {
title: 'Grid Filters Example',
height: 400,
width: 700,
modal: true,
layout: 'fit',
items: grid
}).show();
grid.getStore().load();
Just couldnt figure out what I am doing wrong. Appreciate any help in fixing this issue.
Is there any reason to fetch all the data from server?
I'd recommend using data paging with all the pros, speed being the first one (and some cons too). If you choose to use an infinite grid, it will work well. In fact the basic idea behind infinite grid is fetching data in chunks (data paging in other words).
Filtering works without any problems with this scenario, see sample. It's usually handled by server, which is built to do this kind of tasks.
I hope someone helps me out.
I want to load my grid with xml file's data, locally.
I created model,store and grid. I load the store in render event of grid.
The problem is,
Store is loaded but the grid is still empty. I looked at the grid at console, and grids items contains the loaded data, but grid doesnt contain the data on the screen.
Here is the model
Ext.define('BTOM.model.test.test', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' },
{ name: 'phone', type: 'string' }
]
});
Here is the store
Ext.define('BTOM.store.test.test', {
extend: 'Ext.data.Store',
model: 'BTOM.model.test.test',
autoLoad: false,
proxy: {
type: 'memory',
reader: {
type: 'xml',
root: 'users',
record: 'user'
}
}
});
And the grid
Ext.define('BTOM.view.test.test', {
extend: 'Ext.grid.Panel',
store: 'BTOM.store.test.test',
alias: 'widget.test',
title: 'Test',
initComponent: function () {
this.columns =
[
{ header: "Id", width: 120, dataIndex: 'id', sortable: false },
{ header: "Name", width: 180, dataIndex: 'name', sortable: false },
{ header: "Phone", width: 115, dataIndex: 'phone', sortable: false}
];
this.callParent(arguments);
},
});
And where I load the store is
render: function (grid, eOpts) {
var store = grid.getStore();
var data =
'<?xml version="1.0" encoding="utf-8"?>' +
'<users> ' +
'<user><id>1</id><name>Bll QASD</name><phone>333 2211</phone></user> ' +
'<user><id>2</id><name>Asd QWF</name><phone>444 2211</phone></user> ' +
'<user><id>3</id><name>Zas QWE</name><phone>555 2211</phone></user> ' +
'</users>';
var dataXml = (new DOMParser()).parseFromString(data, 'text/xml');
console.log(dataXml);
store.loadRawData(dataXml, true);
console.log(grid);
}
dataXML document is created without problem.
grid seems to contain the data (by firebug, I can see)
but datagrid is empty, doesnt show the data!
Ok, the error is that you are defining the store but not creating it.
So the grid just has the name of the store but it expects a store instance,
or is that some thing you have missed in the code snippet above.
I used the same code and here is a running example:
https://fiddle.sencha.com/#fiddle/oel
I am using Extjs4 and I want to apply exactMatch on grid filtering. I am using the newly introduced Grid Filtering feature.I have tried to use exactMatch but it does not work. Here is my sample code:
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'ID', type: 'string'},
{name: 'Title', type: 'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'MyModel',
proxy: {
type: 'ajax',
url: 'myurl',
reader: {
type: 'json'
}
},
sorters: [{
property: 'ID',
direction:'DESC'
}],
autoLoad:true
});
var filters = {
ftype: 'filters',
encode: true,
local: true,
filters: [{
type: 'numeric',
dataIndex: 'ID',
disabled: true
},{
type: 'string',
dataIndex: 'Title',
exactMatch:true
}]
};
var grid = Ext.create('Ext.grid.Panel', {
store: store,
columns: [{
header: 'ID',
dataIndex: 'ID',
width: 20
},{
header: 'List Title',
dataIndex: 'Title',
flex:1
}],
renderTo: 'editor-grid',
width: 700,
height: 400,
frame: true,
features: [filters]
});
Thanks..
It looks like for ExtJS V4.0, you don't have to configure seperate filter options for the grid as they are already included. You can just call the method on the store to filter after the data has been loaded like so:
store.filter("Title", "Bob");
or if you want to do multiple filters like so:
store.filter([
{property: "email", value: "Bob"},
{filterFn: function(item) { return item.get("ID") > 10; }}
]);
The grid's features property can only contain classes that have been extended from the Feature class.
See the Grouping Feature:
Ext.define('Ext.grid.feature.Grouping', {
extend: 'Ext.grid.feature.Feature',
alias: 'feature.grouping'
// More properties and functions...
}
Grouping Feature Usage:
var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
groupHeaderTpl: 'Group: {name} ({rows.length})', //print the number of items in the group
startCollapsed: true // start all groups collapsed
});
var grid = Ext.create('Ext.grid.Panel', {
features:[groupingFeature]
}