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']));
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 can send a parameter from as3 to asp. And I can get a value from db. But unfortunatelly I cant combine both of them. Is it possible to send a ID parameter from as3 to asp where I want to make a sql query on a db. Then query result will return back to the as3. Users can login with their id number. And they can see their own datas on the as3 application. My sample codes are given:
I can send values with these codes:
var getParams:URLRequest = new URLRequest("http://www***********/data.asp");
getParams.method = URLRequestMethod.POST;
var paras:URLVariables = new URLVariables();
paras.parameter1 = ""+userID;
getParams.data = paras;
var loadPars:URLLoader = new URLLoader(getParams);
loadPars.addEventListener(Event.COMPLETE, loadCompleted);
loadPars.dataFormat = URLLoaderDataFormat.VARIABLES;
loadPars.load(getParams);
function loadCompleted(event:Event):void
{
trace("sent")
}
I can get values from db with these codes:
var urlLoader:URLLoader =new URLLoader();
urlLoader.load(new URLRequest("http://www***********/data.asp"));
urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
urlLoader.addEventListener(Event.COMPLETE, onXMLLoad);
function onXMLLoad(event:Event):void
{
var loader:URLLoader = URLLoader(event.target);
var scrptVars:URLVariables = new URLVariables(loader.data +"");
returnParameter= scrptVars.LINK0;
high.HighScore.text = returnParameter + "";
}
What is the logic of combining them?
Sory for my English level :)
To combine the second one into the first, you just need to read the URLLoader's data property (which is the response from the server) on the loadCompleted method (same as you're doing in the onXMLLoad method):
function loadCompleted(event:Event):void
{
trace("sent and received", loadPars.data);
high.HighScore.text = loadPars.data.LINK0;
}
The COMPLETE event for a URLLoader fires once the request has received a response. If your server adds data to that response, it can be found in the data property of the URLLoader.
So to summarize, sending and receiving can be done all in one operation with one URLLoader. The data you send to the server, is found in the URLRequest object passed to the URLLoader, the data that comes back from that request, is found in the data property of the URLLoader object (but only after the COMPLETE event fires).
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:
So I have a page in which a user is selecting from a list of available options via checkboxes.
I have 3 collections: One for possible list of options, one for the currently saved options, and a clone of the saved options. I am using the clone list to add/remove options as they click on checkboxes.
var possibleOptions = new Backbone.Collection("/options");
var currentUserOptions = new Backbone.Collection("/useroptions", { id: 2 });
var clonedUserOptions = new Backbone.Collection(currentUserOptions.toJSON());
The reason this approach was taken is that a user can cancel out of the options page mid edit so want the options persisted upon clicking a save button. The clonedOptions are updated correctly as options are checked/unchecked. However, when I try to update the real list nothing seems to happen.
currentUserOptions.update(clonedUserOptions.toJSON());
My expectation was that backbone would trigger post request for the new models and deletes for each missing model according to the docs (http://documentcloud.github.com/backbone/#Collection-update). Please let me know if I am misunderstanding how this is suppose to work. A simple working example of the right approach would be greatly appreciated.
Thanks,
CF
It is my understand that you have to update the server with individual model calls when the collection changes (as people have mentioned). There are events to cover these changes. However, you can send the entire collection using sync. When each model is added or removed you can flag it as new and deleted and when you are ready to save send the entire collection. Your server methods will have to take care of determining the appropriate add or delete operation then when the collection is sent.
Here is an example of doing a bulk sync. Instead of using this.collection.remove() you may just want to flag as deleted as I mentioned. This is pretty much the only way the server would know what to delete. Technically you could delete everything and then just add what is sent in the bulk update :) Also you might have to do another get or return a collection from the server when you save to update what has actually been removed. I am not sure this helps in your case, but I have used it for pages that "save when done" one button concept.
var one = new model({ id: this.collection.length + 1});
var two = new model({ id: this.collection.length + 2 });
var three = new model({ id: this.collection.length + 3 });
var four = new model({ id: this.collection.length + 4 });
var five = new model({ id: this.collection.length + 5 });
this.collection.add(one.toJSON());
this.collection.add(two.toJSON());
this.collection.add(three.toJSON());
this.collection.add(four.toJSON());
this.collection.add(five.toJSON());
this.collection.sync('update', this.collection, { success: function () { console.log(this.collection.length); } });
this.collection.remove(one);
this.collection.remove(two);
this.collection.sync('update', this.collection, { success: function () { console.log(this.collection.length); } });
And in your case:
currentUserOptions.sync('update', currentUserOptions, { success: function () { //do something } });
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...
}