ExtJS Grid with Remote Buffered Store Fails to Render First Page - extjs

ExtJS version: 4.1.0
I have an infinite-scrolling grid with remote buffered store declared as follows:
Ext.define('App.store.UserGridStore', {
extend: 'Ext.data.Store',
autoLoad: true,
buffered: true,
pageSize: 30,
leadingBufferZone:60,
trailingBufferZone:60,
scrollToLoadBuffer:20,
numFromEdge:20,
clearOnPageLoad:false,
isSortable: true,
remoteSort: true,
proxy: {
type: 'ajax',
url: 'Service/data',
reader: {
type: 'json',
root: 'data',
noCache: true,
successProperty: 'success',
totalProperty: 'total'
}
}
});
On a page with a few pages of rows, when a user scrolls down all the way and then back up to page 1, the grid re-renders all pages except for page 1 (for which it just shows blank space).
The store appears to correctly fire a query to my backend service and the service returns the correct data. However, the data is not rendered on the grid.
Any pointers to solve this issue? Thanks.

This problem went away after I set pageSize to a much larger number (300). It probably happened because the store couldn't handle too many AJAX calls due to the low pageSize (30).

Related

ExtJs (6.0.0) rest service PUT request

I am trying to PUT some data from my frontend (ExtJs) into my backend (Java, Spring). It does not work or I do not get the right clue...
I am on a Ext.grid.Panel where I use the following store which is (nicely) filled and displayed by a this.store.setData( myObject.data.items ) method:
Ext.define( 'NameOfThisClass', {
extend: 'Ext.grid.Panel',
...
store: Ext.create( 'Ext.data.Store', {
data: [],
autoLoad: false,
proxy: {
type: 'rest',
url: '/somepath/theclass',
reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'totalCount'
},
writer: {
type: 'json'
},
}
} ),
...
// setting the data to be visualized
setValue: function(myObject) {
this.store.setData( myObject.data.items );
}
...
updateRecord: function(objectId, objectWithUpdateProperties) {
// do what with the store and/or proxy?
}
...
});
I display all entries in a table. The entries are not automatically loaded by the store but set from outside: setValue(myObject).
There is another store for initially loading the data. The data received is then splittet and forwarded in order not to have several requests.
I do get a nice visualized table whose entries are editable by the rowediting plugin.
Ok, so far the backgrounds.
When editing the table's data I run through some validations and gather more data via a modal dialog and then I have the data in order to send to the server by a call of updateRecord(objectId, objectWithUpdateProperties).
This sending is my problem. I do not know how to call/send a rest/put request which will be read by the server. (Receiving is not the problem, sending is).
I guess I somewhat need to trigger my store or the store's proxy. But how?
It is not that I can simply tell my object to save since I do have more data than just the changed object's properties.
Can anyone help me here?
I normally use Ext.Ajax to achieve that, like this:
updateRecord: function(objectId, objectWithUpdateProperties) {
Ext.Ajax.request({
url: 'YourUrl',
params: {
some_param: 'some_value',
object_id: objectId,
object_with_properties_param1: objectWithUpdateProperties.param1
},
success: function(response, opts) {
//Horay, Do something with the response
},
failure: function(response, opts) {
//Oh nooooo
}
});
}
Don't need to use Ajax.
You need to config proxy.api CRUD(C:create, R:read, U:Update. D:Delete) on RestProxy, from client side.
Also, store must have autoSync:true.
At server side, need to config a #RestController for each one of CRUD (with JSON-Java encoder for parameters like Jackson or equivalent), that will acept JSON data. Take into account, that you may send only modified field (store.proxy.writer.writeAllFields: false ->>> default) or just the full record (.writeAllFields:true) to server.
Here an example (inside store's constructor):
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
autoSync: true,
model: 'Test.model.Country',
proxy: {
type: 'rest',
api: {
create: 'country/create',
read: 'counrtry/list'
update: 'counrtry/update',
destroy: 'counrtry/destroy'
},
writer:{
writeAllFields : true
},
reader:{
root:'items',
totalProperty: 'rowCount'
}
}
}, cfg)]);
}
Extra note: For reading from server and load store automatically, just set store.autoLoad: true, and the corresponding #RestController method from server side. Take into account the store.reader params.

ExtJS 5 load existing store with local data

I am doing unit testing and would like to add dummy data to an existing store. In the function I am testing, I am calling a store:
var tripStore = Ext.getStore('Trips');
Normally, this store would have been populated by an Ajax call at a previous point. However, since I am testing I want to use dummy data and not rely on the back end. I realize I could rewrite the function to pass in the store, but I do not want to rewrite this for the sake of testing.
Bottom line, how do I add local data to a store that already exists but has no data in it? Furthermore, the back end is not available, so when I try store.load or store.reload it throws a 404 saying it cannot find the url rest/trip. I don't want it to try and call this url, but instead I want to add local data.
The model definition:
Ext.define('app.model.Trip', {
fields:[
{name: 'someField1', type: 'string'},
{name: 'someField2', type: 'string'},
{name: 'someField3', type: 'string'},
],
proxy: {
noCache: true,
url: 'rest/trip',
reader: {
type: 'json',
rootProperty: 'trips'
}
}
});
The (attempted) test script that is calling the url when I don't want it to, but only want it to add the local data:
var tripsStore = Ext.StoreManager.lookup('Trips');
tripsStore.load({
autoLoad: false,
addRecords: true,
proxy: {
data: localData,
},
callback: function(records, operation, success) {
if (success) {
debugger
} else {
debugger
}
}
})
Use ajax.SimManager. See example (open Details on the right-hand side, click on any of the Data tabs).

Making a good pagination for a grid - extJS

I'm new to ExtJS.
I followed a tutorial with the aim to create a pagination on a grid.
The code was simple, and I found it suspicious...
as result, the paging toolbar is there but there are still all the data displayed on the first load.
Here's my code in the View file :
Ext.define('AM.view.user.List' ,{
extend: 'Ext.grid.GridPanel',
alias: 'widget.userlist',
cls: 'overall',
title: 'xxx <img src="ressource/image/xxx.png" class="title-icon" style= "width: 5%; height: 5%; vertical-align:middle; margin-bottom:0px;" />',
columnLines: true,
dockedItems: [{
xtype: 'pagingtoolbar',
store: 'Users',
pageSize: 2,
dock: 'bottom',
displayInfo: true
}],
I also saw tutorial with a var, but I dont' know where to implement it.
I'm sorry I know there is many tutorials about it out of there but I'm struggling on it :(, I don't mastery JS enough !
Thanks by advance ^_^
edit :
My code in my Store file :
var itemsPerPage = 2;
var store = Ext.define('AM.store.Users', {
pageSize: itemsPerPage,
extend: 'Ext.data.Store',
model: 'AM.model.User',
proxy: {
type: 'ajax',
api: {
read: 'application/data/users.json',
update: 'application/data/updateUsers.json',
},
reader: {
type: 'json',
root: 'users',
idProperty: 'POC',
successProperty: 'success',
totalProperty : 'total'
}
},
autoLoad: false,
});
store.load({
params:{
start:0,
limit: itemsPerPage
}
});
This is telling me : Uncaught TypeError: Object function constructor() { ... has no method 'load'
I tried to remove the store.load, and add {start: 0, limit: 2} after the AutoLoad, according with this http://www.objis.com/formationextjs/lib/extjs-4.0.0/docs/api/Ext.toolbar.Paging.html
With this method, the toolbar shows me " 2-13 data displayed " as it should but there is not data displayed in the grid :'(.
Your server-side stack (PHP, .NET, whatever) will need to be aware of the page, start, and limit parameters that are passed through as part of the request. This is what you'll use to create the proper SQL query (or whatever is being done to retrieve the records) to limit the results to match the paging accommodated by the store.
I'm guessing you're getting all the results because your app server is sending back all the results. The paging provided by ExtJS is really just a handshake with whatever code is running on the server...the paging in a remote store isn't limiting the records, your server-side code is. The AJAX request that the store's proxy sends merely tells the server what it expects to receive back as data.
This is telling me : Uncaught TypeError: Object function constructor()
{ ... has no method 'load'
The reason it is telling you this is because you are trying to invoke the load() method on the 'class' instead of on an instance:
var store = Ext.define('AM.store.Users', {
Ext.define defines a class. To get an instance, you should call Ext.create:
var store = Ext.create('AM.store.Users', { /* ... */ });
This should happen after the 'class' has been defined, but before you invoke the load.
Maybe you should make it a habit to store the result of Ext.define in a variable with a name starting with an uppercase letter, so you can see it represents a class and not an instance:
var Users = Ext.define('AM.store.Users', {
Pagination in a grid requires a buffered store. Something like this
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
// snip
buffered: true,
pageSize: 5
// snip
proxy: {
type: 'ajax',
api: {
read: 'application/data/users.json',
update: 'application/data/updateUsers.json',
},
reader: {
type: 'json',
root: 'users',
idProperty: 'POC',
successProperty: 'success',
totalProperty: 'yourTotalProperty'
}
}
});
Check the outgoing requests (chrome developer tools, firebug or fiddler). If they add page info (page and pageSize) to the Users-requests then your Ext Js code is correct. And of course you also need a web service that supports paging and delivers the requested data chunks.

Store not seeing changes on grid in extjs4

I am trying to save the changes from the grid to the store but I am not really sure if I'm doing it the right way.
STORE:
store_jvhdr = new Ext.data.JsonStore({
model: 'model_jvhdr',
proxy: {
type: 'ajax',
api: {
read: './journalservlet?batNbr='+batNbr+'&operation=GET_RECORD',
update: './journalservlet',
create: './journalservlet'
},
reader: {
type: 'json',
root: 'data'
}
},
autoLoad: true,
listeners: {
load: function(store, records, successful){
...
}
}
});
This are the listeners attached to the grid
listeners: {
itemdblclick: function(dv, record, item, index, e){
...
},
edit: function(editor, e){
console.log('test');
store_jvdtl.commitChanges();
store_jvdtl.sync();
}
}
Am I missing something?
Using store_jvdtl.sync(); is correct but I don't think you want to call commitChanges() the reason for this is that commitChanges() marks the records in the store as 'clean' or rather, removes their dirty state.
As a result, when you call sync() the store doesn't think it has any changes to send, so I'd have thought you wouldn't get the ajax requests made to your proxy api urls.

extjs ajax proxy updating

I'm started to use ExtJs4 and have question about ajax proxy. My store looks like this:
var users = new Ext.data.Store({
model: 'User',
autoDestroy: true,
autoSync: true,
autoLoad: true
proxy: new Ext.data.HttpProxy({
type: 'ajax',
api: {
create: '../users.php?action=create',
read: '../users.php',
update: '../users.php?action=update',
destroy: '../users.php?action=delete'
},
reader: {
type: 'json',
root: 'users',
idProperty: 'USRID'
}
}),
});
when I remove some records from this store without page refreshing, it seems that all previous deleted items are stored somewhere and sended to php script on every new update. When I refresh page, first remove is ok, but any next remove again accumulate previous removed records.
What I do wrong and how I can fix it?
You might try:
model.commit();
http://docs.sencha.com/ext-js/4-0/#/api/Ext.data.Model-method-commit
Check the reply you are sending from php page. If you are sending some data that it can't understand as success then it will accumulate previous records. e.g. in Spring make return type void and add attribute #ResponseBody send default ok reply else we need to parse response on client side.

Resources