4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
13 * @class Roo.data.JsonReader
14 * @extends Roo.data.DataReader
15 * Data reader class to create an Array of Roo.data.Record objects from a JSON response
16 * based on mappings in a provided Roo.data.Record constructor.
18 * The default behaviour of a store is to send ?_requestMeta=1, unless the class has recieved 'metaData' property
19 * in the reply previously.
24 var RecordDef = Roo.data.Record.create([
25 {name: 'name', mapping: 'name'}, // "mapping" property not needed if it's the same as "name"
26 {name: 'occupation'} // This field will use "occupation" as the mapping.
28 var myReader = new Roo.data.JsonReader({
29 totalProperty: "results", // The property which contains the total dataset size (optional)
30 root: "rows", // The property which contains an Array of row objects
31 id: "id" // The property within each row object that provides an ID for the record (optional)
35 * This would consume a JSON file like this:
37 { 'results': 2, 'rows': [
38 { 'id': 1, 'name': 'Bill', occupation: 'Gardener' },
39 { 'id': 2, 'name': 'Ben', occupation: 'Horticulturalist' } ]
42 * @cfg {String} totalProperty Name of the property from which to retrieve the total number of records
43 * in the dataset. This is only needed if the whole dataset is not passed in one go, but is being
44 * paged from the remote server.
45 * @cfg {String} successProperty Name of the property from which to retrieve the success attribute used by forms.
46 * @cfg {String} root name of the property which contains the Array of row objects.
47 * @cfg {String} id Name of the property within a row object that contains a record identifier value.
48 * @cfg {Array} fields Array of field definition objects
50 * Create a new JsonReader
51 * @param {Object} meta Metadata configuration options
52 * @param {Object} recordType Either an Array of field definition objects,
53 * or an {@link Roo.data.Record} object created using {@link Roo.data.Record#create}.
55 Roo.data.JsonReader = function(meta, recordType){
60 totalProperty: 'total',
61 successProperty : 'success',
66 Roo.data.JsonReader.superclass.constructor.call(this, meta, recordType||meta.fields);
68 Roo.extend(Roo.data.JsonReader, Roo.data.DataReader, {
73 * @prop {Boolean} metaFromRemote - if the meta data was loaded from the remote source.
74 * Used by Store query builder to append _requestMeta to params.
77 metaFromRemote : false,
79 * This method is only used by a DataProxy which has retrieved data from a remote server.
80 * @param {Object} response The XHR object which contains the JSON data in its responseText.
81 * @return {Object} data A data block which is used by an Roo.data.Store object as
82 * a cache of Roo.data.Records.
84 read : function(response){
85 var json = response.responseText;
87 var o = /* eval:var:o */ eval("("+json+")");
89 throw {message: "JsonReader.read: Json object not found"};
95 this.metaFromRemote = true;
96 this.meta = o.metaData;
97 this.recordType = Roo.data.Record.create(o.metaData.fields);
98 this.onMetaChange(this.meta, this.recordType, o);
100 return this.readRecords(o);
103 // private function a store will implement
104 onMetaChange : function(meta, recordType, o){
111 simpleAccess: function(obj, subsc) {
118 getJsonAccessor: function(){
120 return function(expr) {
122 return(re.test(expr))
123 ? new Function("obj", "return obj." + expr)
133 * Create a data block containing Roo.data.Records from an XML document.
134 * @param {Object} o An object which contains an Array of row objects in the property specified
135 * in the config as 'root, and optionally a property, specified in the config as 'totalProperty'
136 * which contains the total size of the dataset.
137 * @return {Object} data A data block which is used by an Roo.data.Store object as
138 * a cache of Roo.data.Records.
140 readRecords : function(o){
142 * After any data loads, the raw JSON data is available for further custom processing.
146 var s = this.meta, Record = this.recordType,
147 f = Record ? Record.prototype.fields : null, fi = f ? f.items : [], fl = f ? f.length : 0;
149 // Generate extraction functions for the totalProperty, the root, the id, and for each field
151 if(s.totalProperty) {
152 this.getTotal = this.getJsonAccessor(s.totalProperty);
154 if(s.successProperty) {
155 this.getSuccess = this.getJsonAccessor(s.successProperty);
157 this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
159 var g = this.getJsonAccessor(s.id);
160 this.getId = function(rec) {
162 return (r === undefined || r === "") ? null : r;
165 this.getId = function(){return null;};
168 for(var jj = 0; jj < fl; jj++){
170 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
171 this.ef[jj] = this.getJsonAccessor(map);
175 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
177 var vt = parseInt(this.getTotal(o), 10);
182 if(s.successProperty){
183 var vs = this.getSuccess(o);
184 if(vs === false || vs === 'false'){
189 for(var i = 0; i < c; i++){
192 var id = this.getId(n);
193 for(var j = 0; j < fl; j++){
195 var v = this.ef[j](n);
197 Roo.log('missing convert for ' + f.name);
201 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
205 raw : { errorMsg : "JSON Reader Error: fields or metadata not available to create Record" },
211 var record = new Record(values, id);
219 totalRecords : totalRecords
222 // used when loading children.. @see loadDataFromChildren
223 toLoadData: function(rec)
225 // expect rec just to be an array.. eg [a,b,c, [...] << cn ]
226 var data = typeof(rec.data.cn) == 'undefined' ? [] : rec.data.cn;
227 return { data : data, total : data.length };