source: trunk/web/addons/job_monarch/lib/extjs/source/data/JsonReader.js @ 619

Last change on this file since 619 was 619, checked in by ramonb, 15 years ago

lib/:

  • added new AJAX dependancies: ExtJS, pChart, Lightbox2
File size: 9.1 KB
Line 
1/*
2 * Ext JS Library 2.2.1
3 * Copyright(c) 2006-2009, Ext JS, LLC.
4 * licensing@extjs.com
5 *
6 * http://extjs.com/license
7 */
8
9/**
10 * @class Ext.data.JsonReader
11 * @extends Ext.data.DataReader
12 * Data reader class to create an Array of {@link Ext.data.Record} objects from a JSON response
13 * based on mappings in a provided {@link Ext.data.Record} constructor.<br>
14 * <p>
15 * Example code:
16 * <pre><code>
17var Employee = Ext.data.Record.create([
18    {name: 'firstname'},                  // Map the Record's "firstname" field to the row object's key of the same name
19    {name: 'job', mapping: 'occupation'}  // Map the "job" field to the row object's "occupation" key
20]);
21var myReader = new Ext.data.JsonReader({
22    totalProperty: "results",             // The property which contains the total dataset size (optional)
23    root: "rows",                         // The property which contains an Array of row objects
24    id: "id"                              // The property within each row object that provides an ID for the record (optional)
25}, Employee);
26</code></pre>
27 * <p>
28 * This would consume a JSON object of the form:
29 * <pre><code>
30{
31    results: 2,
32    rows: [
33        { id: 1, firstname: 'Bill', occupation: 'Gardener' },         // a row object
34        { id: 2, firstname: 'Ben' , occupation: 'Horticulturalist' }  // another row object
35    ]
36}
37</code></pre>
38 * <p>It is possible to change a JsonReader's metadata at any time by including a
39 * <b><tt>metaData</tt></b> property in the data object. If this is detected in the
40 * object, a {@link Ext.data.Store Store} object using this Reader will reconfigure
41 * itself to use the newly provided field definition and fire its
42 * {@link Ext.data.Store#metachange metachange} event. In
43 * undergoing this change, the Store sets its {@link Ext.data.Store#sortInfo sortInfo} property
44 * from the <tt>sortInfo</tt> property in the new metadata. Note that reconfiguring a Store
45 * potentially invalidates objects which may refer to Fields or Records which no longer exist.</p>
46 *
47 * <p>The <b><tt>metaData</tt></b> property may contain any of the configuration
48 * options for this class. Additionally, it may contain a <b><tt>fields</tt></b>
49 * property which the JsonReader will use as an argument to {@link Ext.data.Record#create}
50 * to configure the layout of the Records which it will produce.<p>
51 * Using the <b><tt>metaData</tt></b> property, and the Store's {@link Ext.data.Store#metachange metachange} event,
52 * it is possible to have a Store-driven control initialize itself. The metachange
53 * event handler may interrogate the <b><tt>metaData</tt></b> property (which
54 * may contain any user-defined properties needed) and the <b><tt>metaData.fields</tt></b>
55 * property to perform any configuration required.</p>
56 *
57 * <p>To use this facility to send the same data as the above example without
58 * having to code the creation of the Record constructor, you would create the
59 * JsonReader like this:</p><pre><code>
60var myReader = new Ext.data.JsonReader();
61</code></pre>
62 * <p>The first data packet from the server would configure the reader by
63 * containing a metaData property as well as the data:</p><pre><code>
64{
65    metaData: {
66        totalProperty: 'results',
67        root: 'rows',
68        id: 'id',
69        fields: [
70            {name: 'name'},
71            {name: 'occupation'}
72        ]
73    },
74    results: 2,
75    rows: [
76        { 'id': 1, 'name': 'Bill', occupation: 'Gardener' },
77        { 'id': 2, 'name': 'Ben', occupation: 'Horticulturalist' }
78    ]
79}
80</code></pre>
81 * @cfg {String} totalProperty Name of the property from which to retrieve the total number of records
82 * in the dataset. This is only needed if the whole dataset is not passed in one go, but is being
83 * paged from the remote server.
84 * @cfg {String} successProperty Name of the property from which to retrieve the success attribute used by forms.
85 * @cfg {String} root name of the property which contains the Array of row objects.
86 * @cfg {String} id Name of the property within a row object that contains a record identifier value.
87 * @constructor
88 * Create a new JsonReader
89 * @param {Object} meta Metadata configuration options.
90 * @param {Object} recordType Either an Array of field definition objects as passed to
91 * {@link Ext.data.Record#create}, or a {@link Ext.data.Record Record} constructor created using {@link Ext.data.Record#create}.
92 */
93Ext.data.JsonReader = function(meta, recordType){
94    meta = meta || {};
95    Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
96};
97Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
98    /**
99     * This JsonReader's metadata as passed to the constructor, or as passed in
100     * the last data packet's <b><tt>metaData</tt></b> property.
101     * @type Mixed
102     * @property meta
103     */
104    /**
105     * This method is only used by a DataProxy which has retrieved data from a remote server.
106     * @param {Object} response The XHR object which contains the JSON data in its responseText.
107     * @return {Object} data A data block which is used by an Ext.data.Store object as
108     * a cache of Ext.data.Records.
109     */
110    read : function(response){
111        var json = response.responseText;
112        var o = eval("("+json+")");
113        if(!o) {
114            throw {message: "JsonReader.read: Json object not found"};
115        }
116        return this.readRecords(o);
117    },
118
119    // private function a store will implement
120    onMetaChange : function(meta, recordType, o){
121
122    },
123
124    /**
125         * @ignore
126         */
127    simpleAccess: function(obj, subsc) {
128        return obj[subsc];
129    },
130
131        /**
132         * @ignore
133         */
134    getJsonAccessor: function(){
135        var re = /[\[\.]/;
136        return function(expr) {
137            try {
138                return(re.test(expr))
139                    ? new Function("obj", "return obj." + expr)
140                    : function(obj){
141                        return obj[expr];
142                    };
143            } catch(e){}
144            return Ext.emptyFn;
145        };
146    }(),
147
148    /**
149     * Create a data block containing Ext.data.Records from a JSON object.
150     * @param {Object} o An object which contains an Array of row objects in the property specified
151     * in the config as 'root, and optionally a property, specified in the config as 'totalProperty'
152     * which contains the total size of the dataset.
153     * @return {Object} data A data block which is used by an Ext.data.Store object as
154     * a cache of Ext.data.Records.
155     */
156    readRecords : function(o){
157        /**
158         * After any data loads, the raw JSON data is available for further custom processing.  If no data is
159         * loaded or there is a load exception this property will be undefined.
160         * @type Object
161         */
162        this.jsonData = o;
163        if(o.metaData){
164            delete this.ef;
165            this.meta = o.metaData;
166            this.recordType = Ext.data.Record.create(o.metaData.fields);
167            this.onMetaChange(this.meta, this.recordType, o);
168        }
169        var s = this.meta, Record = this.recordType,
170            f = Record.prototype.fields, fi = f.items, fl = f.length;
171
172//      Generate extraction functions for the totalProperty, the root, the id, and for each field
173        if (!this.ef) {
174            if(s.totalProperty) {
175                    this.getTotal = this.getJsonAccessor(s.totalProperty);
176                }
177                if(s.successProperty) {
178                    this.getSuccess = this.getJsonAccessor(s.successProperty);
179                }
180                this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
181                if (s.id) {
182                        var g = this.getJsonAccessor(s.id);
183                        this.getId = function(rec) {
184                                var r = g(rec);
185                                return (r === undefined || r === "") ? null : r;
186                        };
187                } else {
188                        this.getId = function(){return null;};
189                }
190            this.ef = [];
191            for(var i = 0; i < fl; i++){
192                f = fi[i];
193                var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
194                this.ef[i] = this.getJsonAccessor(map);
195            }
196        }
197
198        var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
199        if(s.totalProperty){
200            var v = parseInt(this.getTotal(o), 10);
201            if(!isNaN(v)){
202                totalRecords = v;
203            }
204        }
205        if(s.successProperty){
206            var v = this.getSuccess(o);
207            if(v === false || v === 'false'){
208                success = false;
209            }
210        }
211        var records = [];
212            for(var i = 0; i < c; i++){
213                    var n = root[i];
214                var values = {};
215                var id = this.getId(n);
216                for(var j = 0; j < fl; j++){
217                    f = fi[j];
218                var v = this.ef[j](n);
219                values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n);
220                }
221                var record = new Record(values, id);
222                record.json = n;
223                records[i] = record;
224            }
225            return {
226                success : success,
227                records : records,
228                totalRecords : totalRecords
229            };
230    }
231});
Note: See TracBrowser for help on using the repository browser.