source: Dev/branches/rest-dojo-ui/client/dojox/data/RailsStore.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 4.8 KB
Line 
1define(["dojo", "dojox", "dojox/data/JsonRestStore"], function(dojo, dojox) {
2
3// Contains code donated by Travis Tilley under CLA
4dojo.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
167return dojox.data.RailsStore;
168});
Note: See TracBrowser for help on using the repository browser.