Is there a simple way to export a grid data to XLS in ExtJS.
If not I am trying the following way.
I am trying to read the data store inside a controller. The datastore is already being used by the grid. I want to read the data on a button click and send it to server through AJAX. Later inside server I would retrieve the data and write to XLS. In this case what is the way I can read the data inside the controller?
enter code here
Ext.define("MyApp.controller.GridController", {
extend : 'Ext.app.Controller',
views: ['performance.grid.PerformanceGrid'],
models: ['GridModel'],
stores: ['GridStore'],
refs : [{
ref : 'mainTabPanel',
selector : 'portal > tabpanel'
}],
init : function() {
this.control({
'portal toolbar > button[itemId=xls]' : {
click : this.onAddTab
},
'portal toolbar > button[itemId=pdf]' : {
click : this.onAddPortlet
}
});
},
onAddTab : function(btn, e) {
// I want to read the datastore here and make an AJAX call
},
});
onAddTab: function(btn, e){
var store = // get the store reference probably doing Ext.getStore('the store');
var records = store.data.items.map(function(r){ return r.data });
// send it all to your server as you want to
// Ext.ajax.Request({
// url: 'the url',
// data: records,
// method: 'POST'
// });
});
I didn´t test it but it have to work.
Good luck!
I think that process is not the best because you will have 3 payloads (data round trips that doesn't make any sense)
Your call your server method to get the data that will be populated into the grid.
The JSON object (containing the server data) will then travel again to the server
(THIS DOESN'T MAKE SENSE TO ME... WHY YOU WANT TO SEND DATA TO SERVER WHEN THE SERVER WAS THE SOURCE?? )
The server will process your object from JSON response and then create the document on the fly and send it back to server.
What I think you should do is the following:
Get data from server and bind your grid.
Get your store proxy URL and parse the method and extraParams so you know who served the grid and what you asked to the server.
Create a common method on server that receives a method and an array of parameters. Then inside this method make the logic so depending on the method, you call your data Repository (same repository where your first request got the data), process the document and send the file back to server.
This way you should have something like this:
webmethod(string method, object[] params) {
switch(method){
case "GetTestGridData":
// here you call your Repository in order to get the same data
GeneralRepo repo = new GeneralRepo();
var data = repo.GetTestGridData(object[0],object[1]);
break;
}
byte[] fileStream = Reports.Common.Generate(data, ExportType.PDF);
// response the stream to client...
}
Related
In my store I am calling load on a store. It is hitting the server and getting a bunch of data, however my data is not in the records object.
Instead the data I want is in the operation.response object.
store.load({
params: postBody,
callback: function (records, operation, success) {
if (success) {
console.info('seccuess')
var decoded = Ext.decode(operation.response.responseText);
if(decoded.success && decoded.result.length > 0){
var results = decoded.result; //results are in record array here!!!
}
}
}
});
The records object is returning something that is not what I want.
All the records seem to be in the operation.response object (see results variable). I didn't write this code so I can't explain the reasoning behind this.
Bottom line : How do I inject/set/put these results into the store?
Is there something like this :
this.setData(results)
that I can call in the callback object? The proxy magic going on behind the scenes is trying to apply the records object onto my grid.
I have a grid with remote data (php/mysql/json) and use a form to insert records or to edit this data.
I use the api configuration of the proxy/store. I use MVC architecture.
So, all very simple (in pseudo code):
get selected model form grid or create model
frm.loadRecord()
frm.updateRecord()
frm.getRecord().save()
and all works fine, but I noticed in the browser console that after the POST (works fine, calls either the url configured with create or the url configured with update), the store calls (GET) the url configured with retrieve twice. These calls are identical.
So functionally all works fine and I could ignore it, but now I've noticed I want it fixed.
Can anyone help me where to look? Thanks in advance.
Details:
It's all really basic:
In the controller of the gridpanel:
updateRow: function (gridpanel) {
var sm = gridpanel.getSelectionModel();
var record = sm.getLastSelected();
this.showForm(record);
}
and
showForm: function (record) {
...
formpanel.show();
var frm = formpanel.getForm();
frm.loadRecord(record);
}
In the controller of the formpanel:
submit: function(frm) {
frm.updateRecord();
frm.getRecord().save();
}
When I remove the save action the GET requests aren't called, so this seems to trigger them.
In the store:
api: {
create: '../php/api/customers.php?request=create',
read: '../php/api/customers.php?request=retrieve&scope=summary',
update: '../php/api/customers.php?request=update',
destroy: '../php/api/customers.php?request=delete'
}
The screenshot:
For now I use this code to save new/exist record:
var values = this.getFrmDetails().getValues();
var record = this.getFrmDetails().getRecord();
var store = Ext.getStore('usersStore');
record.set(values);
// Is this a new user?
if (record.data.id==-1)
{
record.save();
store.add(record);
}
store.load();
this.getMainView().pop();
This code works fine, but it always saves & loads the whole data again, I'm tracking records by id so when I add new record I pass: -1 for id.
If not using store.load(), the id will be always -1 for new records till I reload my app.
How can I update the new record with id which created at server side?
I use REST proxy with PHP server side, MySQL database.
By the way in Firebug I always see PUT for new/updated records. How can I make Sencha touch send POST only for new records and PUT for just updating existing one?
I have autosync=true on store.
Thank you
I'm using C# instead PHP but I use the same '-1' Id technique. When I insert a record in the store and sync with remote I return the inserted records and the store takes the values from the service response.
var store = Ext.getStore('fooStore');
var newFoo = {
a: 'a',
b: 'b'
};
store.add(newFoo) // here the record id would be -1
store.sync({
callback: function () {
// here the id is the returned from the server
// this is not needed if you have autoSync, It's just for clearness
}
});
And me C# code structure would be:
function Foo Insert(Foo foo) {
var myTable = new MyTable(); // In PHP would be different, but I guess that the idea is clear.
var newRecord = myTable.Insert(foo); // The insert method returns the added record.
return newRecord;
}
Then the returned record would be taken by the model or the store definition and the Id will be automatically updated. If you use this, there is no need to use the store.load() method, because the response has the needed information for update.
For the kind of request POST instead of PUT, you have to use this in your Model/Store proxy definition:
// ...
proxy: {
// ...
actionMethods: {
create: 'POST',
read: 'POST',
update: 'POST',
destroy: 'POST'
}
// ...
}
// ...
I found a solution:
var newid=-1;
record.save({success : function(res){newid=res.getId();}});
record.data.id=newid;
PHP side:
$sql="SELECT LAST_INSERT_ID() id";
$rs=mysql_query($sql);
$db_field = mysql_fetch_assoc($rs);
echo json_encode(array("success"=>$db_field['id']));
OK, I'm stuck on what should be a basic task in ExtJs. I'm writing a simple login script that sends a user name and password combination to a RESTful web service and receives a GUID if the credentials are correct.
My question is, do I use a Model Proxy or a Store Proxy?
To my understanding, Models represent a single record, whereas Stores are for handling sets of data containing more than one record. If this is correct then it would seem that a Model proxy is the way to go.
Following Sencha's documentation at http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Model the code would look something like this:
Ext.define('AuthenticationModel', {
extend: 'Ext.data.Model',
fields: ['username', 'password'],
proxy: {
type: 'rest',
url : '/authentication'
}
});
//get a reference to the authentication model class
var AuthenticationModel = Ext.ModelManager.getModel('AuthenticationModel');
So far everything is OK, until the next step:
//Use the configured RestProxy to make a GET request
AuthenticationModel.load('???', {
success: function(session) {
console.log('Login successful');
}
});
The load() method for the Model class is a static call expecting a single unique identifier. Logins typically depend upon two factors, username and password.
So it appears Store proxies are the only way to validate someone's username and password credential combination in ExtJS. Can someone verify and explain? Any help to understand this would be greatly appreciated.
You just need to know the following:
The store will use it's own proxy if you configured one for this
instance and if not he takes the proxy from the model.
So you can easily go with two proxy configurations to enable the multi-CRUD operations on the store and the single-CRUD operations on the Models. Note the the static load method of the Model expects the model id because it is supposed to load a model by just one Id (yes, composite keys are not supported). You will also have to fetch the model instance in the callback (As you did).
Back to your Username/password problem
You may apply your session Model with a custom 'loadSession' method
loadSession: function(username,password, config) {
config = Ext.apply({}, config);
config = Ext.applyIf(config, {
action: 'read',
username: username,
password: password
});
var operation = new Ext.data.Operation(config),
scope = config.scope || this,
callback;
callback = function(operation) {
var record = null,
success = operation.wasSuccessful();
if (success) {
record = operation.getRecords()[0];
// If the server didn't set the id, do it here
if (!record.hasId()) {
record.setId(username); // take care to apply the write ID here!!!
}
Ext.callback(config.success, scope, [record, operation]);
} else {
Ext.callback(config.failure, scope, [record, operation]);
}
Ext.callback(config.callback, scope, [record, operation, success]);
};
this.getProxy().read(operation, callback, this);
}
Now call this instead of load.
I found it in the documentation of sencha App Architecture Part 2
Use proxies for models:
It is generally good practice to do this as it allows you to load and
save instances of this model without needing a store. Also, when
multiple stores use this same model, you don’t have to redefine your
proxy on each one of them.
Use proxies for stores:
In Ext JS 4, multiple stores can use the same data model, even if the
stores will load their data from different sources. In our example,
the Station model will be used by the SearchResults and the Stations
store, both loading the data from a different location. One returns
search results, the other returns the user’s favorite stations. To
achieve this, one of our stores will need to override the proxy
defined on the model.
i am working in extjs+Yii. My client side functionality is desighned in yii and server side functionality is in extjs. In extjs controller i had written code to send dynamically generate store,set its proxy and using sync() method of store.
review:function()
{ var reviewQuestionStore=Ext.create('Balaee.store.qb.QbqnsStore');
proxy=reviewQuestionStore.getProxy();
Ext.apply(proxy.api,{
read:'http://127.0.0.1/s_balaee/Balaee/index.php/QuestionBank/Qbpaper/ReviewQuestionPaper',
create:'http://127.0.0.1/s_balaee/Balaee/index.php/QuestionBank/Qbpaper/ReviewQuestionPaper',
});
Ext.apply(proxy.writer,{
type:'json',
root:'records'
});
Ext.apply(proxy.reader,{
type:'json',
root:'questions'
});
var getdata=this.getLocalvalue();
UserId=getdata.data.userId;
//Using sync method
var check =Ext.create('Balaee.model.qb.QbqnsModel',{
questionPaperNo:Paperno,
userId: UserId,
});
reviewQuestionStore.add(check);
reviewQuestionStore.sync();
}
So its working corectly. And its sending data in json format as-
{"records":{"userId":"5","firstName":"abc","middleName":"","lastName":"","languageId":"","primaryEmail":"sdf#sdf.dfg","birthDate":"","password":"","securityQuestionId":"","securityQuestionAnswer":"","isMale":"","creationTime":"","ipAddress":"","confirmationCode":"","userStatusId":"","question":"","id":null}}
Now i want to catch this data in yii controller function. i had tried as-
$postData = json_decode(file_get_contents("php://input"), true);
$clientData = $postData['records'];
and to access fields i am using $clientData['firstName'].But its not working.So how to catch data in Yii which is send via Extjs's store sync() method.
Use Standard Yii Json decode.It will create array for you
$data= CJSON::decode(file_get_contents("php://input"));