source: Dev/trunk/src/client/dojox/data/RailsStore.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 4.7 KB
Line 
1define(["dojo", "dojox", "dojox/data/JsonRestStore"], function(dojo, dojox) {
2
3// Contains code donated by Travis Tilley under CLA
4return dojo.declare("dojox.data.RailsStore", dojox.data.JsonRestStore, {
5        constructor: function(){
6                // summary:
7                //              RailsStore is a data store for interacting with RESTful Rails controllers
8        },
9        preamble: function(options){
10                if(typeof options.target == 'string' && !options.service){
11                        var target = options.target.replace(/\/$/g, '');
12
13                        // Special getRequest handler for handling content type negotiation via
14                        // the Rails format extension, as well as properly setting the ID param
15                        // in the URL.
16                        var getRequest = function(id, args){
17                                args = args || {};
18                                var url = target;
19                                var query;
20                                var ident;
21
22                                if(dojo.isObject(id)){
23                                        ident = '';
24                                        query = '?' + dojo.objectToQuery(id);
25                                }else if(args.queryStr && args.queryStr.indexOf('?') != -1){
26                                        ident = args.queryStr.replace(/\?.*/, '');
27                                        query = args.queryStr.replace(/[^?]*\?/g, '?');
28                                }else if(dojo.isString(args.query) && args.query.indexOf('?') != -1){
29                                        ident = args.query.replace(/\?.*/, '');
30                                        query = args.query.replace(/[^?]*\?/g, '?');
31                                }else{
32                                        ident = id ? id.toString() : '';
33                                        query = '';
34                                }
35
36                                if(ident.indexOf('=') != -1){
37                                        query = ident;
38                                        ident = '';
39                                }
40
41                                if(ident){
42                                        url = url + '/' + ident + '.json' + query;
43                                }else{
44                                        url = url + '.json' + query;
45                                }
46
47                                var isSync = dojox.rpc._sync;
48                                dojox.rpc._sync = false;
49
50                                return {
51                                        url : url,
52                                        handleAs : 'json',
53                                        contentType : 'application/json',
54                                        sync : isSync,
55                                        headers : {
56                                                Accept : 'application/json,application/javascript',
57                                                Range : args && (args.start >= 0 || args.count >= 0)
58                                                                ? "items="
59                                                                                + (args.start || '0')
60                                                                                + '-'
61                                                                                + ((args.count && (args.count
62                                                                                                + (args.start || 0) - 1)) || '')
63                                                                : undefined
64                                        }
65                                };
66                        };
67
68                        options.service = dojox.rpc.Rest(this.target, true, null,
69                                        getRequest);
70                }
71        },
72        fetch: function(args){
73                args = args || {};
74                function addToQueryStr(obj){
75                        function buildInitialQueryString(){
76                                if(args.queryStr == null){
77                                        args.queryStr = '';
78                                }
79                                if(dojo.isObject(args.query)){
80                                        args.queryStr = '?' + dojo.objectToQuery(args.query);
81                                }else if(dojo.isString(args.query)){
82                                        args.queryStr = args.query;
83                                }
84                        }
85                        function separator(){
86                                if(args.queryStr.indexOf('?') == -1){
87                                        return '?';
88                                }else{
89                                        return '&';
90                                }
91                        }
92                        if(args.queryStr == null){
93                                buildInitialQueryString();
94                        }
95                        args.queryStr = args.queryStr + separator() + dojo.objectToQuery(obj);
96                }
97                if(args.start || args.count){
98                        // in addition to the content range headers, also provide query parameters for use
99                        // with the will_paginate plugin if so desired.
100                        if((args.start || 0) % args.count){
101                                throw new Error("The start parameter must be a multiple of the count parameter");
102                        }
103                        addToQueryStr({
104                                page: ((args.start || 0) / args.count) + 1,
105                                per_page: args.count
106                        });
107                }
108                if(args.sort){
109                        // make the sort into query parameters
110                        var queryObj = {
111                                sortBy : [],
112                                sortDir : []
113                        };
114
115                        dojo.forEach(args.sort, function(item){
116                                queryObj.sortBy.push(item.attribute);
117                                queryObj.sortDir.push(!!item.descending ? 'DESC' : 'ASC');
118                        });
119
120                        addToQueryStr(queryObj);
121                        delete args.sort;
122                }
123
124                return this.inherited(arguments);
125        },
126        _processResults: function(results, deferred){
127                var items;
128
129                /*
130                 * depending on the ActiveRecord::Base.include_root_in_json setting,
131                 * you might get back an array of attribute objects, or an array of
132                 * objects with the attribute object nested under an attribute having
133                 * the same name as the (remote and unguessable) model class.
134                 *
135                 * 'Example' without root_in_json: [{'id':1, 'text':'first'}]
136                 * 'Example' with root_in_json: [{'example':{'id':1, 'text':'first'}}]
137                 */
138                if((typeof this.rootAttribute == 'undefined') && results[0]){
139                        if(results[0][this.idAttribute]){
140                                this.rootAttribute = false;
141                                console.debug('RailsStore: without root_in_json');
142                        }else{
143                                for(var attribute in results[0]){
144                                        if(results[0][attribute][this.idAttribute]){
145                                                this.rootAttribute = attribute;
146                                                console.debug('RailsStore: with root_in_json, attribute: ' + attribute);
147                                        }
148                                }
149                        }
150                }
151
152                if(this.rootAttribute){
153                        items = dojo.map(results, function(item){
154                                return item[this.rootAttribute];
155                        }, this);
156                }else{
157                        items = results;
158                }
159
160                // index the results
161                var count = results.length;
162                // if we don't know the length, and it is partial result, we will guess that it is twice as big, that will work for most widgets
163                return {totalCount:deferred.fullLength || (deferred.request.count == count ? (deferred.request.start || 0) + count * 2 : count), items: items};
164        }
165});
166
167});
Note: See TracBrowser for help on using the repository browser.