I am using extjs sencha store for storing data. I make a proxy call to a web-service to get data. I refresh the data using store.load() function.
I am looking to edit the data that is received before it is given to the grid.
I know about the load event, but this function is executed after the load is completed and data is populated with the current data.
listeners : {
'load' : function(store,records, options) {
}
},
I am looking to see how I can edit the returned data from web-service before it is assigned to the store. Basically data returned from my webservice is in different format than the format we give to extjs datagrid. So, want to do a data operation before we give to the grid. Hope we can do this.
Thx
Model mappings can help you do this. There is a conversion function that can be supplied as well. Here is the example from the docs:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{
name: 'firstName',
convert: function(value, record) {
var fullName = record.get('name'),
splits = fullName.split(" "),
firstName = splits[0];
return firstName;
}
},
'name', 'email',
{name: 'age', type: 'int'},
{name: 'gender', type: 'string', defaultValue: 'Unknown'}
]
});
Related
I am working on a web app which needs to populate a grid with some data. I have a button wired with a onClick method which opens a new modal window for the grid to be displayed. I am using a jquery post call to the controller. However, I am unable to get the json data and assign it to my variable.
My code is as follows:
var grid_ds;
$.post('${ctx}/class/student/details?studentId=${student.studentId}', function(data){
}, 'json');
$('#student_grid').kendoGrid({
dataSource: grid_ds,
columns: [
{field: "studentName", title: "Student Name"},
{field: "studentClass", title: "Class"}
],
dataBound: function () {
emptyGrid($('#student_grid'));
}
}).data('kendoGrid');
My controller sends json back. I can see the data coming. How should I assign the json data to grid_ds and student_grid and make the values populate in the grid.
You could try using a kendo.data.DataSource with a custom transport function like so:
$('#student_grid').kendoGrid({
dataSource: dataSource = new kendo.data.DataSource({
transport: {
read: function (e) {
$.post('${ctx}/class/student/details?studentId=${student.studentId}', 'json')
.done(function (data) {
e.success(data);
});
}
}
}),
columns: [
{
field: "studentName",
title: "Student Name"
},
{
field: "studentClass",
title: "Class"
}
]});
I think the problem may be with how you're fetching the data. Since $.post is an ajax call operating out of band, grid_ds is most likely undefined when being passed to the .kendoGrid() function.
I wasn't able to locate the dataBound configuration property that you specify in your question in the kendo.ui.Grid. Do you happen to know where this configuration setting came from?
Also asked on Sencha's site here
My data model's "serialize" function is not called when I call
model.set("<fieldName>", <newValue>);
Here's a fiddle
I'm pretty unclear on why the serialize function isn't called...am I missing something, or is this a bug?
(And here's the code from the fiddle)
Ext.application({
name : 'Fiddle',
requires: [
"Ext.data.Store"
],
launch : function() {
var store = Ext.create("Ext.data.Store", {
data: [{Id: 0, Name: "Bill", Props: "{foo: 2, bar:{pan:5}}"}],
fields:[
{name: "Id", type: "int"},
{name: "Name", type: "string"},
{name: "Props",
convert: function(value, record){
console.log("called convert");
return Ext.JSON.decode(value);
},
serialize: function(value, record){
alert("never getting called!! :(");
console.log("sure, i'll put log here too..not getting called though");
return Ext.JSON.encode(value);
}
}
]
});
console.log(store.getAt(0));
var rec = store.getAt(0);
var newProp = {rec:"junk", foo: "orange"};
console.log(newProp);
rec.set("Props",newProp);
}
});
Mappings from source content (JSON/XML) to business model (Ext.data.Model) are not automatically created in ExtJS's data model system. As such, another step is needed to produce this relationship using mapping/associationsor something similar.
I.e. The data model doesn't store the original JSON to read/write from, which is fine for most cases. When a JSON string needs to be updated via ExtJS, one solution is to, on the model, set
convertOnSet
to false, allowing for custom manipulation of the JSON string via extract/update functions on the data model.
I have store that I would like to initialize from a database but I couldn't find a standard init method for the Ext.data.Store. I found a couple of examples with the StoreManager component, but I think that's not what I'm looking for. I have an MVC structure for my app and I'd like to keep it, I only want to initialize my store's data field using a method I define. Could someone explain how to do so?
I either understand you wrong or your question is straight forward. You configure a store with a model like this. That's all. You may just chose a provider(reader/writer) that fit your needs.
// Set up a model to use in our Store
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstName', type: 'string'},
{name: 'lastName', type: 'string'},
{name: 'age', type: 'int'},
{name: 'eyeColor', type: 'string'}
]
});
Ext.define('YourMVCNameSpace.data.UserStore', {
extend: 'Ext.data.Store',
constructor: function (config) {
config = Ext.Object.merge({}, config);
var me = this;
// do what you need with the given config object (even deletes) before passing it to the parent contructor
me.callParent([config]);
// use me forth on cause the config object is now fully applied
},
model: 'User',
proxy: {
type: 'ajax',
url: '/users.json',
reader: {
type: 'json',
root: 'users'
}
},
autoLoad: true
});
Note that the reader will expect a Json result like this:
{"total": 55, "users":["...modeldata.."]}
and is referring to a url like
http://localhost/YourAppDomain//users.json
Place the store as 'User' within the controller store array and retrieve it within the Controller by calling getUserStore() or directly from the Ext.StoreMgr using Ext.StoreMgr.lookup('User');
Note that by convention the Controller (MVC) will override any storeId you set on the store and will just use the name.
I have a json store loaded, I need to grab one record from it.
I used : getAt(index), find(), getById(), but no results .
This is my code :
var appSettingReader = new Ext.data.JsonReader({
root: 'results',
},[
{name: 'id', type: 'int', mapping: 'id'},
{name: 'projetId', type: 'int', mapping: 'projetId'},
{name: 'resLevels', type: 'int', mapping: 'resLevels'},
{name: 'maxResToLock', type: 'int', mapping: 'maxResToLock'},
{name: 'maxTimeToLock', type: 'int', mapping: 'maxTimeToLock'},
{name: 'infosToPrint', type: 'string', mapping: 'infosToPrint'}
])
var appSettingStore = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'inc/getSettings.php',
method: 'POST'
}),
baseParams:{task: "app"},
reader : appSettingReader,
sortInfo:{field: 'id', direction: "DESC"}
})
appSettingStore.load();
This code return undefined :
console.log(appSettingStore.getAt(0));
console.log(appSettingStore.find("id","1"));
This is the json string returned from server :
{success:true,"results":[{"id":"1","projetId":"1","resLevels":"1","maxResToLock":"40","maxTimeToLock":"10","infosToPrint":"1_2_3_5","hotlineMail":"admin#app.com"}]}
I've also tested this code :
var records = new Array()
var test = appSettingStore.each(function(rec){
records.push(rec)
})
console.log(records)
and I get an empty array !
PS : This store is not bound to any component;
I just want to read and write to it.
You need to place a callback on the store, that will be fired after it loads. You can then use the data as required.
store.load({
callback : function(r, options, success) {
console.log(r.data)
}
})
It appears the server is returning invalid JSON. Why does your server-side script's output start with "("?
If that's not actually the problem, maybe you should consider accepting some more answers to your questions. People will be more likely to help.
EDIT: Okay, so you're pretty sure you're getting valid json back from the server. Try adding a 'success' property to your server's output.
If that doesn't work, you'll want to dig in a little more. Try adding a callback option to your store's .load(), and look at the stuff that gets passed into the callback. That should help you figure out where things are going wrong.
I'm trying to learn how to use the EXTJS grids for some simple CRUD operations over a table in a admin app.
I have a simple grid that allows someone to edit users, the store is defined as:
var userDataStore = new Ext.data.Store({
id: 'userDataStore',
autoSave: false,
batch: true,
proxy: new Ext.data.HttpProxy({
api: {
read: '/Admin/Users/All',
create: '/Admin/Users/Save',
update: '/Admin/Users/Save'
}
}),
reader: new Ext.data.JsonReader(
{
root: 'Data',
idProperty: 'ID',
totalProperty: 'total',
successProperty: 'success',
messageProperty: 'message'
}, [
{ name: 'ID', type: 'string', allowBlanks: false },
{ name: 'NT_ID', type: 'string', allowBlank: false },
{ name: 'EMail', type: 'string', allowBlank: false },
{ name: 'Name', type: 'string', allowBlank: false },
{ name: 'Enabled', type: 'bool', allowBlank: false },
{ name: 'CurrentRoleCode', type: 'string', allowBlank: false}]
),
writer: new Ext.data.JsonWriter(
{
encode: false,
writeAllFields: true,
listful: true
})
});
This is bound to a grid, and I am able to load and save users without issue. The save button looks like this:
var saveButton = new Ext.Button({
text: 'Save',
disabled: true,
handler: function() {
userDataStore.save();
pageState.ClearDirty();
saveButton.disable();
}
});
However, when creating a new user, the JSON POST for the user is posted to the same REST service end point as "Update", with the only difference being that no ID value is posted (as one is only set in the store when loading from the server).
This works, and I am able to create users.
The save REST service emits back the created row with the new database ID, and I was under the assumption that EXTJS would automatically bind the new generated database ID to the row. This allows the user to further edit that row, and cause an update instead of a insert.
Instead, the row continues to have a blank user ID, so an additional save creates another new user.
So either:
EXTJS is supposed to resolve generated row ID's automatically and I am just doing something wrong.
I am supposed to manually reload the grid after each save with an additional REST call.
I've been looking at EXTJS documentation and forums, but I am unclear on the proper approach.
Can someone clarify?
EDIT: I tried returning Success = True in JSON to match the SuccessProperty, however this still didn't seem to work.
EDIT #2: So far the only thing I've found that works is doing "userDataStore.reload()" after saving, however because I was returning the contents of the store back after saving, I was hoping that EXTJS would understand that and update the row values.
I've got an idea that may help you. Let't suppose that user added a new
record in grid, in that moment add a new property newRecOrderNo to the record to
identify the record after response. When user will post data to server after
inserting you must get a new ID and associate it to newRecOrderNo
(like Map<Integer,Integer>). Then return json object like that :
{
success : true,
newIdes : {
1 : 23,
2 : 34
}
}
Then when you get response do set proper IDs to records:
userDataStore.each(function(rec){
if(rec.data.newRecOrderNo){
rec.data.ID = response.newIdes[rec.data.newRecOrderNo];
delete rec.data.newRedOrderNo;
}
})
})
Yes, it sets id (and also other fields, if server returns modified values of them), if create ajax backend returns record with set id, at least in extjs 4.1. You should return inserted record, with id set, under 'root' key as json dictionary, in this example root is 'Data', i.e.:
{
"Data": {
"ID": 8932,
"NT_ID": 28738273,
...
"CurrentRoleCode": "aaa",
},
"success": true
}
You need reload store with new params in savebtn handler
like
store.reload();
of course you can add more params to load action