I am creating a dynamic grid (should be paginated) using the data from a POST rest request to server (code below). I am passing the pageid and pagesize to the server during the first request (on load) and it responds back with the appropriate data. I have docked a paging toolbar to grid and now I want to enable pagination on click of next, last etc of the pager. How do I POST a request to server and get back the appropriate data back to reconfigure the grid with the next page's data?
var screenResults = {};
screenResults.pageid =1;
screenResults.pagesize = 10;
screenResults = Ext.JSON.encode(screenResults);
Ext.Ajax.request({
url : 'http://localhost/service/getGridData',
method : 'POST',
timeout: 5000000,
scope: this,
dataType: 'json',
jsonData: screenResults,
success: function(response){
var grid = Ext.getCmp("idSearchResultsGrid");
var gridData = Ext.decode(response.responseText);
var fields = gridData.data.fields;
var newColumns = gridData.data.columns;
var arr = gridData.data.data;
var data = [];
for(var i=0;i<arr.length;i++){
var obj = arr[i].resultsMap;
data.push(obj);
}
var newStore = Ext.create('Ext.data.Store', {
storeId: 'DynamicGridStore',
pageSize:10,
fields: fields,
data: data
/*
proxy: {
type: 'ajax',
url : 'http://localhost/service/getGridData',
method : 'POST',
timeout: 5000000,
jsonData: screenResults,
actionMethods: {
read : 'POST'
}
}
*/
});
//debugger;
/*
globalStore = newStore.load({
params: {
start: 0,
limit: 10
}
});
*/
var pagingBar = Ext.create('Ext.PagingToolbar', {
pageSize: 10,
store: newStore,
dock: 'bottom',
displayInfo: true
});
grid.removeDocked(grid.getDockedItems()[1]);
grid.addDocked(pagingBar);
grid.reconfigure(newStore, newColumns);
},
failure: function(response){
console.log(response);
}
});
},
First of all, you don't need to explicitly do AJAX calls like that. They will be done for you behind the scenes by the store's proxy — provided that the proxy is properly configured (yours is commented out at the moment).
Your task is very trivial and covered by multiple examples. Have a look at this one. Click on Details on the right hand side to see the code.
Also see Ext.toolbar.Paging documentation.
Related
I study examples on ExtJs 6 and try to repeat. Here is an example of changing the remote storage to the local one https://habr.com/en/en/post/138054/ and trying to repeat.
The difficulty was caused by these code fragments.
UsersApp.Utils.ping({
success: this._onPingSuccess, // Internet is
failure: this._onPingFailure // No Internet
}, this);
where
_onPingSuccess: function(){
// сеть есть
var win = Ext.ComponentQuery.query('#usersWindow')[0];
var storeLocal = this.getStore('storeLocal');
var store = this.getStore('store');
var grid = win.getComponent('NamesGrid');
UsersApp.Utils.ping is a wrapper over Ext.Ajax.request, but the author does not disclose the code. When _onPingSuccess or _onPingFailure is executed, this refers to the Window object that does not have a getStore method.
Full controller code
Ext.define("Apple.controller.Main", {
extend: 'Ext.app.Controller',
requires: [
'Apple.utils.Ping',
'Apple.store.OrderStore',
'Apple.store.UserStore'
],
init: function(){
Ext.define("Session", {
extend: "Ext.data.Session",
});
var session = Ext.create("Session");
var store = Ext.create("Apple.store.OrderStore", {
storeId: 'OrderStore',
session: session
});
store.setProxy(
Ext.create('Ext.data.RestProxy', {
type: 'rest',
url: 'https://localhost:5001/api/order',
api: {
create: 'https://localhost:5001/api/order',
read: 'https://localhost:5001/api/order',
update: 'https://localhost:5001/api/order',
destroy: 'https://localhost:5001/api/order'
},
writer: {
type: 'json',
writeAllFields : false, //just send changed fields
allowSingle : true //always wrap in an array
},
reader: {
type: 'json',
rootProperty: 'data',
successProperty: 'success'
}
})
);
var local = Ext.create("Apple.store.OrderStore", {
storeId: 'OrderStoreLocal',
session: session
});
local.setProxy(
Ext.create('Ext.data.proxy.LocalStorage', {
type: 'localstorage',
id : 'Orders'
})
);
local.addListener('load', function(){
Apple.utils.Ping.sendPing({
success: this._onPingSuccess,
failure: this._onPingFailure
}, this);
}, this);
// initiate loading in local storage
local.load();
},
_onPingSuccess: function(response, options){
var store = this.getStore('OrderStore');
var local = this.getStore('OrderStoreLocal');
var grid = Ext.getCmp('LayC0Grid');
// find out the number of records in the local storage
localCnt = local.getCount();
// check the status of the local storage,
// figure out if synchronization is needed
if (localCnt > 0){
// synchronization is needed, add entries
// one by one from local storage
// to server
for (i = 0; i < localCnt; i++){
var localRecord = local.getAt(i);
var deletedId = localRecord.data.id;
delete localRecord.data.id;
store.add(localRecord.data);
localRecord.data.id = deletedId;
}
// save server storage
store.sync();
// we clear local storage
for (i = 0; i < localCnt; i++){
local.removeAt(0);
}
}
store.load();
// we connect server storage to the table
grid.reconfigure(store);
grid.store.autoSync = true;
},
_onPingFailure: function(response, options){
var local = this.getStore('OrderStoreLocal');
var store = this.getStore('OrderStore');
var grid = Ext.getCmp('LayC0Grid');
// set table storage to local
grid.reconfigure(storeLocal);
grid.store.autoSync = true;
}
});
How do I get storage in _onPingSuccess and _onPingFailure without passing them explicitly?
Assuming that the wrapper has been written properly (read as: following ExtJS' typical usage patterns), you can set the scope property when calling the sendPing method, as follows:
local.addListener('load', function(){
Apple.utils.Ping.sendPing({
success: this._onPingSuccess,
failure: this._onPingFailure,
scope: this
}, this);
}, this);
If, on the other hand, the wrapper wasn't written properly you can then resort to the bind method, as follows:
local.addListener('load', function(){
Apple.utils.Ping.sendPing({
success: this._onPingSuccess.bind(this),
failure: this._onPingFailure.bind(this)
}, this);
}, this);
At this point the function will run in the scope of the controller, so you should be able to retrieve your store easily.
I want to save value received by AJAX response to Ext JS proxy in a JavaScript array. My code look like this:
var nodelist = [];
var store = Ext.create('Ext.data.Store', {
model: 'Nodes',
url: 'sequencing',
proxy: {
type: 'ajax',
url: 'sequencing',
reader: {
type: 'json',
root: 'Nodes'
}
},
listeners: {
'load': function() {
var StoreLength = store.data.length;
for (var i = 0; i < StoreLength; i++) {
nodelist.push(store.data.items[i].data.text);
};
}
},
autoLoad: true
});
store.load();
var node_rec = nodelist;
But the store.load(); does not call the load listener above? Can some one solve my problem?
store.load() is called at the exit of current event handler. Loading of a data store happens asynchronously so by the time it loads the store the execution continues from the next line. So you cannot directly use the nodelist variable after calling load because load will not be called at that point so nodelist will be empty even though the store gets populated eventually.
So you can add a callback to the load method which gets called once the store loads.
store.load({
callback: function(records){
console.log(records); //verify whether you are getting records from the URL
}
});
I have read all the posts on Stackoverflow regarding this issue and tried the following:
1) Adding $.param({}) wrapper
messages.fetch({
data: $.param({ limit: 14 }),
});
2)
Setting traditional to true
messages.fetch({
data: { limit: 14 },
traditional: true
});
3)
Setting processData to true
messages.fetch({
data: { limit: 14 },
processData: true,
});
Despite this, none of these methods work. Is there something I am missing here?
For what I think you're tying to do, you need to use the "url" property on the model/collection. Fetch is a GET type, not a PUT or POST so you aren't sending "data" to the server. Try something like the following:
Note that $.param({ limit: 14 }) returns "limit=14" The point is, that is not a valid serialized object that the server is going to understand.
If your "fetch" method is a "HttpGet"
var MyModel = Backbone.Model.extend({
// place holder for models api. Also look at: http://backbonejs.org/#Model-urlRoot
_baseUrl = 'api/somewhere/great'
// see: http://backbonejs.org/#Model-url
url: function() {
// this returns 'api/somewhere/great?limit=14';
return this._baseUrl + '?' + $.param({ limit: 14 });
}
});
Now, if you want to HttpPut or HttpPost, then you can override "fetch" and do something like the following:
var MyModel = Backbone.Model.extend({
url = 'api/somewhere/great'
fetch: function(options) {
options = options || {
data: {
limit: 14
}
};
/*
signature method of sync: Backbone.sync = function (method, model, options)
*/
return this.sync("create", this, options);
}
});
References:
http://backbonejs.org/#Model-url
http://api.jquery.com/jQuery.param/
Using ExtJS 4.2 - I have an AJAX call populating the store with the entire set of results in JSON format (using loadRawData). I now need to limit the number of results being shown on the grid at a time. End goal is to implement client-side paging. I've tried using pagingmemoryproxy with not much luck.
Ext.define('TestApp.view.TestGrid' , {
extend: 'Ext.grid.Panel',
alias: 'widget.testgrid',
requires:[
'TestApp.store.TestStore'
],
initComponent: function() {
var me = this;
this.store = Ext.create('Ext.data.Store', {
model: 'TestApp.model.TestModel',
proxy: {
type: 'memory',
reader: {
type: 'json'
},
},
pageSize: 20
});
// set the maxRows parameter based on the store's page size
this.maxRows = this.store.pageSize;
this.columns = this.buildColumns();
this.bbar = Ext.create('Ext.PagingToolbar', {
itemId: 'pagingToolbar',
store: this.store,
dock: 'bottom',
displayInfo: true
});
this.callParent();
}
My controller uses the following AJAX call
Ext.Ajax.request({
url: '/testing/test',
method: "POST",
jsonData : requestParams,
timeout: 120000,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
success: function(response) {
var resp = Ext.decode(response.responseText);
var testStore = testGrid.getStore();
var numResults = response.getAllResponseHeaders().resultlength;
// this successfully loads results into store and populates grid
// with pagingtoolbar displaying page 0 of 0
testStore.loadRawData(resp);
//testStore.loadPage(1);
},
You need to add the pagingtoolbar to the grid.
Basically there are three things you need to do:
1) Add paging toolbar to the grid
2) The store used by the grid should be given the 'pageSize' attribute
3) If using loadrawdata, you need to update the toolbar using after you load it. use the loadPage function for that.
The following topic will get you started: How to manage PagingToolbar in Ext-js 4.2 correctly?
I have a grid in Extjs 4.2, the store for it is configured as below.
var userStore = Ext.create('Ext.data.JsonStore', {
model: 'User',
proxy: {
type: 'ajax',
api: {
create: '/pwbench/form/products/fctrmgmt/data.json',
read: '/pwbench/form/products/fctrmgmt/data.json',
update: '/pwbench/form/products/fctrmgmt/data.json',
destroy: '/pwbench/form/products/fctrmgmt/data.json'
},
reader: {
type: 'json'
},
writer: {
type: 'json'
}
},
autoLoad: true
});
Inside the grid, on clicking save I have the following configured.
handler: function() {
var recordsArray = new Array();
var dataRecords = new Array();
recordsArray = grid.getStore().data.items;
for (var i = 0; i < recordsArray.length; i++) {
console.log(recordsArray[i].data);
dataRecords.push(Ext.encode(recordsArray[i].data));
}
console.log(dataRecords.length);
Ext.Ajax.request({
url: 'mainpage.jsp',
params: {
records: dataRecords
},
success: function(response){
var text = response.responseText;
console.log(text);
userStore.sync();
userStore.load();
}
});
}
I have a java class which is able to read the data sent by the ajax request and then I overwrite the data.json file which the store uses to fetch the data. The json file is overwritten without any issue, but the problem is that when I call userStore.load() after sync, it displays the old data, prior to making any changes. Even on refreshing the grid or refreshing the whole page it displays the old data, only when I refresh my entire project in Eclipse and reload the page, then it displays the new overwritten data.
Is this some cache problem? Can someone please tell me what is the issue?
you should put the load in the success callback of the sync
userStore.sync({
success: function() {
userStore.load...