Making a good pagination for a grid - extJS - 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.

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.

How to pass json data from controller to view in EXTJS 4.0

I have a combobox declared inside my grid
header: '<b>Reasons</b>',
width : 150,
editor:
{
xtype: 'combobox',
store: 'reasonstore',
displayField: 'displayText',
valueField: 'value',
queryMode: 'local',
}
and my store is
var reasonstore = Ext.create('Ext.data.Store', {
fields: ['displayText', 'value'],
id : 'resonstoreid'
});
I have done a rest call and got my jsondata in controller
successCallback:function(json){
var mydata = json.reason;
Ext.getCmp('resonstoreid').getStore().loadData(json.reason);
but i m getting Ext.getCmp('resonstoreid') is undefined.
my view is only loading first then the controller.
so how to load this json data from controller to view.
You should use Ext.getStore("xxx") to get a reference to your store! This should solve your problem.
var store = Ext.getStore("resonstoreid");
store.loadData(json.reason);
An other advice
Instead of making a AJAX call, and fill the store with loadData(xxx) use load() function of the store. See here: Ext.data.Store.load
Do to that, your store config should look like this
//create File store/Reasons.js
Ext.define('XYZ.store.Reasons', { //XYZ ... you namespace
extend: 'Ext.data.Store',
fields: ['displayText', 'value'],
id : 'Reasons',
autoLoad: true,
proxy: {
type: 'ajax',
actionMethods: {create: 'POST', read: 'GET', update: 'POST', destroy: 'POST'},
url: 'xxx',
method: 'POST',
reader: {
type: 'json',
root: 'data'
}
}
});
After that, you can do this:
var store = Ext.getStore("Reasons");
store.load(
params: {
group: 3,
type: 'user'
},
callback: function(records, operation, success) {
// do something after the load finishes
},
scope: this
});
The advantage would be a better app structure and that load does the ajax request for you. This is exactly what extjs is great for: Split up the code in many small files which are easy to maintain (code reuse, etc...).

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.

How to set CRUD methods on Sencha Touch 2 proxy/model/store/whatever?

I'm working with a partner to build a Sencha Touch 2 database app. He's built a ton of methods for me on the backend, with syntax like this:
index.php?r=show/update
index.php?r=show/add
index.php?r=show/delete
index.php?r=person/add
Each of which expects a POST to be sent with it.
What I'm struggling with is what the proxies should look like - for instance, is there a way to specify a show proxy that maps /update /add and /delete to their associated U/C/D actions? There's only one url in the proxy, and that is for the get action (getByUser in this case)
I'm assuming that I want to put the other actions into the proxy somehow - or do I just need a bunch of different proxies for each action (that seems kinda redundant...)
The Sencha docs imply that CRUD actions are built-in to proxies, but I don't see where or how their urls get defined...
Ext.define('SMToolkit.store.Shows', {
extend: 'Ext.data.Store',
config: {
model: 'SMToolkit.model.Show',
autoLoad: true,
sorters: 'name',
grouper: {
groupFn: function(record) {
return record.get('type');
}
},
proxy: {
type: 'ajax',
url : 'index.php?r=show/getByUser&username=FOO'
}
}
});
With a model that looks like this:
Ext.define('SMToolkit.model.Show', {
extend: 'Ext.data.Model',
config: {
fields: [
'id',
'name',
'opening',
'closing',
'rehearsal',
'type',
'availability'
]
}
});
When you should have a specific URL for each operation, ST2 provides you with the API property. You should change your proxy to:
proxy: {
type: 'ajax',
api: {
create : 'index.php?r=show/add',
read : 'index.php?r=show/read',
update : 'index.php?r=show/update',
destroy: 'index.php?r=show/delete'
}
}
Please note I removed the url property and added the api property. Also, to delete, you must enter the word 'destroy' because, in Javascript, 'delete' is a reserved word.

JSONP not working on ExtJS 4 - Uncaught TypeError: Cannot call method 'substring' of undefined

I'm stuck with this code, I'm getting this json formated data from the Youtube API, if I use type:'json' it will fail, because of that cross domain thing but the other elements loads anyway; then, if I change type: to 'jsonp' (which is the syntax described on the ExtJS API) it would give me this error:"Uncaught TypeError: Cannot call method 'substring' of undefined" I tried setting type:'anyotherstupidthing' and the same happens, so what could be happening?
Here are my current data model and my store:
Ext.define('Video', {
extend: 'Ext.data.Model',
fields: ['id', 'title']
});
myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
proxy: {
type: 'ajax',
url : 'http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc',
reader: {
type: 'jsonp',
root: 'items'
}
}
});
Thanks in advance!
Ed.
JsonP requires the server to wrap the returned data in a JS function call. The common contract is to pass a parameter named 'callback' to the server to allow for unique names and avoid name clashes on the client.
Calling the URL http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc&callback=myCallback in the browser shows that YouTube support this convention:
Ext supports JsonP via the Ext.data.proxy.JsonP proxy class. The reader is a standard JSON reader and not JsonP specific, you only need to account for the data structure returned from the server (set root to data.items).
The working code looks like this:
var myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
proxy: {
type: 'jsonp',
url : 'http://gdata.youtube.com/feeds/api/videos?q=surfing&v=2&alt=jsonc',
reader: {
type: 'json',
root: 'data.items'
}
},
listeners: {
load: function(store, records) {
Ext.each(records, function(rec) {
console.log(rec.get('title'));
});
}
},
autoLoad: true
});

Resources