ExtJS 4.1 Infinite Grid Scrolling doesnt work with Dynamic store using loadData - javascript

I have to load first grid panel on tab and then load data into store using loadData() function which is working fine, but now I have to integrate infinite grid scrolling with it.
Is there any way to integrate infinite scrolling on fly after loadData into store..? I am using ExtJS 4.1. Please help me out.
Here I am showing my current script in controller and grip view panel in which I have tried out but not working.
Controller Script as below:
var c = this.getApplication().getController('Main'),
data = c.generateReportGridConfiguration(response,true),
tabParams = {
title: 'Generated Report',
closable: true,
iconCls: 'view',
widget: 'generatedReportGrid',
layout: 'fit',
gridConfig: data
},
generatedReportGrid = this.addTab(tabParams);
generatedReportGrid.getStore().loadData(data.data);
On Above script, once I get Ajax call response, adding grid panel with tabParams and passed data with gridConfig param which will be set fields and columns for grid and then last statement supply grid data to grid. I have tried out grid panel settings by following reference example:
http://dev.sencha.com/deploy/ext-4.0.1/examples/grid/infinite-scroll.html
On above page, Included script => http://dev.sencha.com/deploy/ext-4.0.1/examples/grid/infinite-scroll.js
My Grid Panel Script as below:
Ext.define('ReportsBuilder.view.GeneratedReportGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.generatedReportGrid',
requires: [
'ReportsBuilder.view.GenerateViewToolbar',
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.grid.PagingScroller',
'Ext.grid.RowNumberer',
],
initComponent: function() {
Ext.define('Report', {extend: 'Ext.data.Model', fields: this.gridConfig.fields, idProperty: 'rowid'});
var myStore = Ext.create('Ext.data.Store', {model: 'Report', groupField: 'name',
// allow the grid to interact with the paging scroller by buffering
buffered: true,
pageSize: 100,
autoSync: true,
extraParams: { total: 50000 },
purgePageCount: 0,
proxy: {
type: 'ajax',
data: {},
extraParams: {
total: 50000
},
reader: {
root: 'data',
totalProperty: 'totalCount'
},
// sends single sort as multi parameter
simpleSortMode: true
}
});
Ext.apply(this, {
dockedItems: [
{xtype: 'generateviewToolbar'}
],
store: myStore,
width:700,
height:500,
scroll: 'vertical',
loadMask: true,
verticalScroller:'paginggridscroller',
invalidateScrollerOnRefresh: false,
viewConfig: {
trackOver: false,
emptyText: [
'<div class="empty-workspace-bg">',
'<div class="empty-workspace-vertical-block-message">There are no results for provided conditions</div>',
'<div class="empty-workspace-vertical-block-message-helper"></div>',
'</div>'
].join('')
},
columns: this.gridConfig.columns,
features: [
{ftype: 'groupingsummary', groupHeaderTpl: '{name} ({rows.length} Record{[values.rows.length > 1 ? "s" : ""]})', enableGroupingMenu: false}
],
renderTo: Ext.getBody()
});
// trigger the data store load
myStore.guaranteeRange(0, 99);
this.callParent(arguments);
}
});
I have also handled start and limit from server side query but it will not sending ajax request on scroll just fired at once because pageSize property in grid is 100 and guaranteeRange function call params are 0,99 if i will increased 0,299 then it will be fired three ajax call at once (0,100), (100,200) and (200,300) but showing data on grid for first ajax call only and not fired on vertical scrolling.
As, I am new learner on ExtJs, so please help me out...
Thanks a lot..in advanced.

You cannot call store.loadData with a remote/buffered store and grid implementation and expect the grid to reflect this new data.
Instead, you must call store.load.
Example 1, buffered store using store.load
This example shows the store.on("load") event firing.
http://codepen.io/anon/pen/XJeNQe?editors=001
;(function(Ext) {
Ext.onReady(function() {
console.log("Ext.onReady")
var store = Ext.create("Ext.data.Store", {
fields: ["id", "name"]
,buffered: true
,pageSize: 100
,proxy: {
type: 'rest'
,url: '/anon/pen/azLBeY.js'
reader: {
type: 'json'
}
}
})
store.on("load", function(component, records) {
console.log("store.load")
console.log("records:")
console.log(records)
})
var grid = new Ext.create("Ext.grid.Panel", {
requires: ['Ext.grid.plugin.BufferedRenderer']
,plugins: {
ptype: 'bufferedrenderer'
}
,title: "people"
,height: 200
,loadMask: true
,store: store
,columns: [
{text: "id", dataIndex: "id"}
,{text: "name", dataIndex: "name"}
]
})
grid.on("afterrender", function(component) {
console.log("grid.afterrender")
})
grid.render(Ext.getBody())
store.load()
})
})(Ext)
Example 2, static store using store.loadData
You can see from this example that the store.on("load") event never fires.
http://codepen.io/anon/pen/XJeNQe?editors=001
;(function(Ext) {
Ext.onReady(function() {
console.log("Ext.onReady")
var store = Ext.create("Ext.data.Store", {
fields: ["id", "name"]
,proxy: {
type: 'rest'
,reader: {
type: 'json'
}
}
})
store.on("load", function(component, records) {
console.log("store.load")
console.log("records:")
console.log(records)
})
var grid = new Ext.create("Ext.grid.Panel", {
title: "people"
,height: 200
,store: store
,loadMask: true
,columns: [
{text: "id", dataIndex: "id"}
,{text: "name", dataIndex: "name"}
]
})
grid.on("afterrender", function(component) {
console.log("grid.afterrender")
})
grid.render(Ext.getBody())
var data = [
{'id': 1, 'name': 'Vinnie'}
,{'id': 2, 'name': 'Johna'}
,{'id': 3, 'name': 'Jere'}
,{'id': 4, 'name': 'Magdalena'}
,{'id': 5, 'name': 'Euna'}
,{'id': 6, 'name': 'Mikki'}
,{'id': 7, 'name': 'Obdulia'}
,{'id': 8, 'name': 'Elvina'}
,{'id': 9, 'name': 'Dick'}
,{'id': 10, 'name': 'Beverly'}
]
store.loadData(data)
})
})(Ext)

Related

Problems loading the storage in the renderer for the combobox field

My field looks like this:
...
{
xtype: 'gridcolumn',
text: 'MyField',
dataIndex: 'contragent',
editor: {
xtype: 'combobox',
allowBlank: false,
displayField:'name',
valueField:'id',
queryMode:'remote',
store: Ext.data.StoreManager.get('ContrAgents')
},
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
store_ca = Ext.data.StoreManager.get('ContrAgents');
if (record.data.contragent != ''){
store_ca.load();
var contr = store_ca.getById(record.data.contragent);
//indexInStore = store_ca.findExact('id', value);
console.log(contr);
return contr.data.name;
}
}
},
...
Store 'ContrAgents' looks like this:
Ext.define('BookApp.store.ContrAgents', {
extend: 'Ext.data.Store',
model: 'BookApp.model.ContrAgents',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'app/data/Contragents.json'
}
});
The problem is that the name of the required field is not returned (contr.data.name), contr is null.
Apparently the store does not have time to load, in this case I need to load it, but store_ca.load () does not bring results.
How to load the store correctly to use
store_ca.getById (record.data.contragent); to return the name of the field?
I'm not entirely sure why you would need to use a store to populate the value in the grid's cell, because you could always just send the text value through the grid's store as opposed to the id.
You probably have a good reason for doing it, so I've revisited the fiddle and implemented it accordingly. You should be able to check it out here
The changes
../app/store/ContrAgents.js
Ext.define('Fiddle.store.ContrAgents', {
extend: 'Ext.data.Store',
model: 'Fiddle.model.ContrAgents',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'Contragents.json'
}
});
../app/store/ListViewStore.js
Ext.define('Fiddle.store.ListViewStore', {
extend: 'Ext.data.Store',
model: 'Fiddle.model.ListViewModel',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'List.json'
}
});
../app/view/ListView.js
Ext.define('Fiddle.view.ListView' ,{
extend: 'Ext.grid.Panel',
alias: 'widget.booklist',
itemId: 'BookList',
store: 'ListViewStore',
xtype: 'listview',
plugins: 'gridfilters',
initComponent: function() {
var me = this;
// Pin an instance of the store on this grid
me.myContrAgents = Ext.data.StoreManager.lookup('ContrAgents');
// Manually load the 'ContrAgents' first
me.myContrAgents.load(function(records, operation, success) {
// Now load the 'ListViewStore' store
me.getStore().load();
});
me.columns = [
{
header: 'ID',
dataIndex: 'id',
sortable: true,
width: 35
},
{
text: 'Контрагент',
dataIndex: 'contragent',
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
if (value > 0) {
if (rec = me.myContrAgents.findRecord('id', value)) {
return rec.get('name');
}
}
return '';
}
}
];
me.callParent(arguments);
}
});
Data/List.json
"data" : [
{"id": 1, "contragent": "2"},
{"id": 2, "contragent": "3"},
{"id": 3, "contragent": "4"}
]
You are trying to query the store before it's data is actually populated. You want to avoid loading the store for each time the renderer event is triggered.
The Ext.data.Store->load function is asynchronous
See docs
store.load({
scope: this,
callback: function(records, operation, success) {
// the operation object
// contains all of the details of the load operation
console.log(records);
}
});
Change your implementation to this and test if it works
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
store_ca = Ext.data.StoreManager.get('ContrAgents');
if (record.data.contragent != ''){
store_ca.load(function(records, operation, success) {
console.log('loaded records');
var contr = store_ca.getById(record.data.contragent);
indexInStore = store_ca.findExact('id', value);
console.log({
contr: contr,
indexInStore: indexInStore
});
});
// Not sure what you are trying to return here
// return contr.data.name;
}
}
Remote Combo in ExtJS Grid Example
I found a good example for what you are trying to accomplish here with a combo dropdown in a grid with a remote store, check out this post (you might have to register for free but the solution is worth it and I won't plagiarise it here)
Grid with combo edit widget with binding
Perhaps this could help...
Ext.define('Fiddle.view.ListView' ,{
extend: 'Ext.grid.Panel',
alias: 'widget.booklist',
itemId: 'BookList',
store: 'ListViewStore',
xtype: 'listview',
plugins: ['cellediting','gridfilters'],
initComponent: function() {
this.columns = [
{
header: 'ID',
dataIndex: 'id',
sortable: true,
width: 35
},
{
text: 'Контрагент',
width: 150,
xtype: 'widgetcolumn',
dataIndex: 'contragent',
widget: {
xtype: 'combo',
bind: '{record.contragent}',
allowBlank: false,
displayField: 'name',
valueField: 'id',
store: Ext.data.StoreManager.lookup('ContrAgents')
}
}
];
this.callParent(arguments);
}
});

How to load extjs 4 grid data on form submission?

I am new to ExtJS.
I am developing a page which has a form at the top and a grid below. When user enters the search criteria in the form and enters Submit, grid has to be populated with data accordingly.
I have managed to get the JSON data from server to the client
console.log('response.responseText');
prints the data correctly, but unable to assign that to the grid.
Here is my code
Ext.define('colModel', {
extend: 'Ext.data.ColumnModel',
fields: [
'personId',
'country',
'idType',
'idValue'
]
});
// create the data store
var store = Ext.create('Ext.data.ArrayStore', {
model: 'colModel',
fields: [
{name: 'personId'},
{name: 'country'},
{name: 'idType'},
{name: 'idValue'}
],
proxy: {
type: 'ajax',
reader: {
type: 'json',
root: 'person'
}
},
autoLoad: false,
});
// create the Grid
var grid = Ext.create('Ext.grid.Panel', {
store: store,
stateful: true,
id: 'myGrid',
stateId: 'stateGrid',
columns: [
{
text : 'Person Id',
flex : 1,
sortable : false,
dataIndex: 'personId'
},
{
text : 'Country',
width : 75,
sortable : true,
dataIndex: 'country'
},
{
text : 'ID Type',
width : 75,
sortable : true,
dataIndex: 'idType'
},
{
text : 'Id Value',
width : 75,
sortable : true,
dataIndex: 'idValue'
},
],
height: 350,
title: 'Array Grid',
renderTo: 'bottom',
viewConfig: {
stripeRows: true,
ForceFit: true,
loadMask:false
}
});
and this function get invoked after form submission and response returned from server
displayGrid : function(response, opts) {
//Received response from the server
console.log('On Success');
responseData = Ext.decode(response.responseText);
console.log('response success ',responseData);
console.log(Ext.getCmp('myGrid').getStore());
grid.getStore().loadData('colModel',false);
}
I have managed to populate grid data on page load using the following code
var store = Ext.create('Ext.data.ArrayStore', {
model: 'colModel',
proxy: {
type: 'rest',
url : 'PersonSearch',
reader: {
type: 'json',
root: 'person'
}
},
autoLoad: true
});
but failed to load grid data on form submission.
Please help. Thanks in advance.
PS: I am using ExtJS 4.2
Update
This is the JSON update, I am getting from the server(caught using Firefox Browser Console)
"{"person":[{"personId":"1","country":"country 1","idType":"idType 1","idValue":"idValue 1"},{"personId":"2","country":"country 2","idType":"idType 2","idValue":"idValue 2"},{"personId":"3","country":"country 3","idType":"idType 3","idValue":"idValue 3"},{"personId":"4","country":"country 4","idType":"idType 4","idValue":"idValue 4"},{"personId":"5","country":"country 5","idType":"idType 5","idValue":"idValue 5"}]}
"
You aren't actually loading the data. Your data is stored in responseData, so your loadData call should load that data into the store. So, your loadData call should be as follows:
grid.getStore().loadData(responseData);
Note that this assumes that your responseData is in the correct format for the store you are loading it into. (Also note that the second parameter is false by default, so it isn't necessary to include it in this case)
Used forgivenson comment and set autoLoad: true
and
Updated the displayGrid method as below
displayGrid : function(response, opts) {
//Received response from the server
console.log('On Success');
responseData = Ext.decode(response.responseText,false);
console.log(response.responseText);
grid.getStore().loadData(responseData.person);
}
and the grid gets populated correctly.

how to apply navigation in extjs grid

I want to load only 25 rows at a time in grid. After clicking next button next 25 rows should be added. Data in grid is in json format and it is from servlet. I am getting json data from servlet. But i want to load particular part only. How can implement please help me.
Ext.require([
'Ext.data.*',
'Ext.grid.*'
]);
Ext.onReady(function(){
Ext.define('Book',{
extend: 'Ext.data.Model',
fields: [
'sno',
'name', 'salary'
]
});
// create the Data Store
var store = Ext.create('Ext.data.Store', {
model: 'Book',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
//url: 'http://localhost:8080/sampleweb/AccessServlet',
url: 'http://localhost:8080/sampleweb/DataServlet',
// the return will be XML, so lets set up a reader
reader: {
type: 'json',
root:'jsonObj'
}
}
});
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing');
var cellEditing = Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
});
// create the grid
var grid = Ext.create('Ext.grid.Panel', {
store: store,
columns: [
{text: "sno",width:140, dataIndex: 'sno', sortable: true
,editor: {
xtype: 'numberfield',
allowBlank: false,
minValue: 1,
maxValue: 150000
}},
{text: "name", width: 180, dataIndex: 'name', sortable: true,
editor: {
xtype: 'combobox',
typeAhead: true,
triggerAction: 'all',
selectOnTab: true,
store: [
['Shade','Shade'],
['Mostly Shady','Mostly Shady'],
['Sun or Shade','Sun or Shade'],
['Mostly Sunny','Mostly Sunny'],
['Sunny','Sunny']
]}},
{text: "salary", width: 180, dataIndex: 'salary', sortable: true,
editor: {
xtype: 'numberfield',
allowBlank: false,
minValue: 1,
maxValue: 1000000
}},
{
xtype: 'actioncolumn',
width: 30,
sortable: true,
menuDisabled: true,
items: [{
icon: 'http://etf-prod-projects-1415177589.us-east-1.elb.amazonaws.com/trac/docasu/export/2/trunk/client/extjs/shared/icons/fam/delete.gif',
handler: function(grid, rowIndex, colIndex) {
store.removeAt(rowIndex);
}
}]
}
],
renderTo:'example-grid',
width: 560,
plugins: [rowEditing],
height: 400
});
});
You need pagination, take a look at the example provided by Sencha. Basically, all you have to do on the front-end is to add and configure one paging toolbar and the framework takes care about the rest. The real job is on the server side where your servlet will have to parse start and limit parameters, include them in queries and return the appropriate data. This is an example of the request generated by ExtJS once you correctly incorporated paging toolbar:
{
//your request data
..
start: 0,
limit: 25
}
This request will fetch first 25 rows. Of course you can configure the number of rows in your application.
You just have to add
limitParam : 10,
pageParam :'pageNumber',
in the proxy attribute of store. If you want to load a specific page use
grid.getStore().currentPage = The Page Number You Want To Load;
before loading the store.

Extjs 4 cellEditing plugin doesn't work with more then one grid

I have a simple page with 2 or more grids and I want to use CellEditing plugin to edit cells of those grids.
If I have only a grid all works well, but if I make 2 grids (or more) CellEditing plugin stop to work.
Anyone know how to solve this problem?
I have made a little minimized example that is affected with this problem.
In this example you can try to add a row to the first grid and double click to edit that grid. As you can see cell editing doesn't work at all.
If you add and edit the cell in the second grid, it work.
here you can found the example in jsfiddle:
http://jsfiddle.net/eternasparta/amHRr/
and this is the javascript code:
Ext.require([
'Ext.form.*',
'Ext.tip.*']);
var store = Ext.create('Ext.data.Store', {
fields: ['label'],
data: []
});
Ext.define('AM.view.editpanel.CustomList', {
extend: 'Ext.container.Container',
alias: 'widget.sclist',
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'grid',
plugins: [],
selModel: {
selType: 'cellmodel'
},
tbar: [{
text: 'Add',
actionId: 'add',
handler: function (th, e, eArg) {
var store = th.up('grid').store;
var r = Ext.create(store.model.modelName);
store.insert(0, r);
}
}],
height: 200,
store: store,
columns: [{
text: 'Name',
dataIndex: 'label',
flex: 1,
editor: {
xtype: 'numberfield',
allowBlank: false
}
}, {
xtype: 'actioncolumn',
width: 30,
sortable: false,
actionId: 'delete',
header: 'delete',
items: [{
tooltip: 'tool'
}]
}],
flex: 1
}],
flex: 1,
initComponent: function () {
this.items[0].plugins.push(Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 2
}));
this.callParent(arguments);
var sto = Ext.create('Ext.data.Store', {
fields: ['label'],
data: []
});
this.down('grid').bindStore(sto);
this.down('grid').columns[0].text = 'Name';
this.down('grid').columns[0].dataIndex = 'label';
}
});
Ext.onReady(function () {
Ext.QuickTips.init();
var grid1 = Ext.create('AM.view.editpanel.CustomList', {
renderTo: Ext.getBody()
});
var grid2 = Ext.create('AM.view.editpanel.CustomList', {
renderTo: Ext.getBody()
});
});
Any help is appreciated, thank you!
Just put configs of Object or array type (in your case - items) inside initComponent: demo.
For more info see my answer here.
You can create separate objects for each grid like
//For grid 1
var rowEditing1 = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: true
});
//For grid 2
var rowEditing2 = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: true
});
It will create different instances for the different grids. Tested Working fine :)

How to load XML into a list using Sencha/Phonegap?

I'm trying to setup a native style app using sencha touch and phonegap. I'm trying to pull in data from an external XML feed into the model.
In my model (Event.js) I have this:
Ext.regModel('Event', {
fields: [
{name: 'title', type: 'string'}
]
});
In my store (eventsstore.js):
ToolbarDemo.eventstore = new Ext.data.Store({
model: 'Event',
sorters: 'title',
getGroupString : function(record) {
return record.get('title')[0];
},
proxy: {
type: 'ajax',
url: 'http://the-url-to-the-file.xml',
reader: {
type: 'xml',
root: 'events',
record: 'event'
}
},
autoLoad: true
});
And in the view (tried as a list):
ToolbarDemo.views.Eventscard = Ext.extend(Ext.List, {
title: "Events",
iconCls: "search",
store: ToolbarDemo.eventstore,
itemTpl: '{title}',
grouped: true,
indexBar: true,
cardSwitchAnimation: 'slide'
});
Ext.reg('eventscard', ToolbarDemo.views.Eventscard);
And tried as a panel:
ToolbarDemo.views.Eventscard = Ext.extend(Ext.Panel, {
title: "Events",
iconCls: "search",
dockedItems: [{
xtype: 'toolbar',
title: 'Events'
}],
layout: 'fit',
items: [{
xtype: 'list',
store: ToolbarDemo.eventstore,
itemTpl: '{title}',
grouped: true
}],
//This was an experiment, safe to leave out?
initComponent: function() {
//ToolbarDemo.eventstore.load();
ToolbarDemo.views.Eventscard.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('eventscard', ToolbarDemo.views.Eventscard);
Now when I navigate to that card view, the loading overlay/spinner is displayed but that's as far as it goes, the list of items does not appear. Any ideas of what I'm doing wrong?
I am not that much familier with this, I have used like this to display a list.. try this
ToolbarDemo.eventstore.load();
var itemTpl = new Ext.XTemplate('<div id='title'>{title}</div>');
this.eventStoreList = new Ext.List({
id: 'eventStoreList',
store: ToolbarDemo.eventstore,
itemTpl: itemTpl,
height: 370,
indexBar: false
});
this.eventStoreListContainer = new Ext.Container( {
id : 'eventStoreListContainer',
items : [this.eventStoreList]
});
this.items = [this.eventStoreListContainer];
ToolbarDemo.views.Eventscard.superclass.initComponent.apply(this);
Well, I got it working!
I added ToolbarDemo.eventstore.read(); to the end of my store code, saved the XML file locally in the root 'www' folder then using the list method worked fine!
Does any body know why this (calling a remote XML) could be a problem?
EDIT: Turns out that it works fine in the browser like that, but not the iPhone simulator. So now I've set it back to the remote URL and added the URLs to the PhoneGap Whitelist and it works great :)

Categories

Resources