author | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2011-10-02 23:56:18 (UTC) |
---|---|---|
committer | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2011-10-02 23:56:18 (UTC) |
commit | ef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (unidiff) | |
tree | c403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/beta/js/YUI-extensions/data/LoadableDataModel.js | |
parent | 597ecfbc0249d83e1b856cbd558340c01237a360 (diff) | |
download | clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2 |
First version of the newly restructured repository
Diffstat (limited to 'frontend/beta/js/YUI-extensions/data/LoadableDataModel.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI-extensions/data/LoadableDataModel.js | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/data/LoadableDataModel.js b/frontend/beta/js/YUI-extensions/data/LoadableDataModel.js new file mode 100644 index 0000000..07def44 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/data/LoadableDataModel.js | |||
@@ -0,0 +1,330 @@ | |||
1 | /** | ||
2 | * @class YAHOO.ext.grid.LoadableDataModel | ||
3 | * This class extends DefaultDataModel and adds the core functionality to load data remotely. Generally you will want to use one of it's subclasses.<br><br> | ||
4 | * @extends YAHOO.ext.grid.DefaultDataModel | ||
5 | * @constructor | ||
6 | * @param {String} dataType YAHOO.ext.grid.LoadableDataModel.XML, YAHOO.ext.grid.LoadableDataModel.TEXT or YAHOO.ext.grid.JSON | ||
7 | */ | ||
8 | YAHOO.ext.grid.LoadableDataModel = function(dataType){ | ||
9 | YAHOO.ext.grid.LoadableDataModel.superclass.constructor.call(this, []); | ||
10 | |||
11 | /** Fires when a successful load is completed - fireDirect sig: (this) | ||
12 | * @type YAHOO.util.CustomEvent | ||
13 | * @deprecated Use addListener instead of accessing directly | ||
14 | * @private | ||
15 | */ | ||
16 | this.onLoad = new YAHOO.util.CustomEvent('load'); | ||
17 | /** Fires when a load fails - fireDirect sig: (this, errorMsg, responseObj) | ||
18 | * @type YAHOO.util.CustomEvent | ||
19 | * @deprecated Use addListener instead of accessing directly | ||
20 | * @private | ||
21 | */ | ||
22 | this.onLoadException = new YAHOO.util.CustomEvent('loadException'); | ||
23 | /** | ||
24 | * @event load | ||
25 | * Fires when new data has successfully been loaded | ||
26 | * @param {DataModel} this | ||
27 | */ | ||
28 | this.events['load'] = this.onLoad; | ||
29 | /** | ||
30 | * @event beforeload | ||
31 | * Fires before a load takes place | ||
32 | * @param {DataModel} this | ||
33 | */ | ||
34 | this.events['beforeload'] = new YAHOO.util.CustomEvent('beforeload'); | ||
35 | /** | ||
36 | * @event loadexception | ||
37 | * Fires when there's an error loading data | ||
38 | * @param {DataModel} this | ||
39 | * @param {Exception} e The exception object or null | ||
40 | * @param {Object} response The Connect response object | ||
41 | */ | ||
42 | this.events['loadexception'] = this.onLoadException; | ||
43 | |||
44 | /**@private*/ | ||
45 | this.dataType = dataType; | ||
46 | /**@private*/ | ||
47 | this.preprocessors = []; | ||
48 | /**@private*/ | ||
49 | this.postprocessors = []; | ||
50 | |||
51 | // paging info | ||
52 | /** The active page @type Number*/ | ||
53 | this.loadedPage = 1; | ||
54 | /** True to use remote sorting, initPaging automatically sets this to true @type Boolean */ | ||
55 | this.remoteSort = false; | ||
56 | /** The number of records per page @type Number*/ | ||
57 | this.pageSize = 0; | ||
58 | /** The script/page to call to provide paged/sorted data @type String*/ | ||
59 | this.pageUrl = null; | ||
60 | /** An object of key/value pairs to be passed as parameters | ||
61 | * when loading pages/sorting @type Object*/ | ||
62 | this.baseParams = {}; | ||
63 | /** Maps named params to url parameters - Override to specify your own param names */ | ||
64 | this.paramMap = {'page':'page', 'pageSize':'pageSize', 'sortColumn':'sortColumn', 'sortDir':'sortDir'}; | ||
65 | |||
66 | }; | ||
67 | YAHOO.extendX(YAHOO.ext.grid.LoadableDataModel, YAHOO.ext.grid.DefaultDataModel, { | ||
68 | |||
69 | /** @ignore */ | ||
70 | setLoadedPage: function(pageNum, userCallback){ | ||
71 | this.loadedPage = pageNum; | ||
72 | if(typeof userCallback == 'function'){ | ||
73 | userCallback(); | ||
74 | } | ||
75 | }, | ||
76 | |||
77 | /** Returns true if this model uses paging @return Boolean */ | ||
78 | isPaged: function(){ | ||
79 | return this.pageSize > 0; | ||
80 | }, | ||
81 | |||
82 | /** Returns the total number of records available, override if needed @return {Number} */ | ||
83 | getTotalRowCount: function(){ | ||
84 | return this.totalCount || this.getRowCount(); | ||
85 | }, | ||
86 | |||
87 | /** Returns the number of records per page @return Number */ | ||
88 | getPageSize: function(){ | ||
89 | return this.pageSize; | ||
90 | }, | ||
91 | |||
92 | /** Returns the total number of pages available @return Number */ | ||
93 | getTotalPages: function(){ | ||
94 | if(this.getPageSize() == 0 || this.getTotalRowCount() == 0){ | ||
95 | return 1; | ||
96 | } | ||
97 | return Math.ceil(this.getTotalRowCount()/this.getPageSize()); | ||
98 | }, | ||
99 | |||
100 | /** Initializes paging for this model. | ||
101 | * @param {String} url | ||
102 | * @param {Number} pageSize | ||
103 | * @param {Object} baseParams (optional) Object containing key/value pairs to add to all requests | ||
104 | */ | ||
105 | initPaging: function(url, pageSize, baseParams){ | ||
106 | this.pageUrl = url; | ||
107 | this.pageSize = pageSize; | ||
108 | this.remoteSort = true; | ||
109 | if(baseParams) this.baseParams = baseParams; | ||
110 | }, | ||
111 | |||
112 | /** @ignore */ | ||
113 | createParams: function(pageNum, sortColumn, sortDir){ | ||
114 | var params = {}, map = this.paramMap; | ||
115 | for(var key in this.baseParams){ | ||
116 | if(typeof this.baseParams[key] != 'function'){ | ||
117 | params[key] = this.baseParams[key]; | ||
118 | } | ||
119 | } | ||
120 | params[map['page']] = pageNum; | ||
121 | params[map['pageSize']] = this.getPageSize(); | ||
122 | params[map['sortColumn']] = (typeof sortColumn == 'undefined' ? '' : sortColumn); | ||
123 | params[map['sortDir']] = sortDir || ''; | ||
124 | return params; | ||
125 | }, | ||
126 | |||
127 | /** | ||
128 | * Loads a page of data. | ||
129 | * @param {Number} pageNum Which page to load. The first page is 1. | ||
130 | * @param {Function} callback (optional) Optional callback when loading is complete | ||
131 | * @param {Boolean} keepExisting (optional) true to keep existing data and append the new data | ||
132 | */ | ||
133 | loadPage: function(pageNum, callback, keepExisting){ | ||
134 | var sort = this.getSortState(); | ||
135 | var params = this.createParams(pageNum, sort.column, sort.direction); | ||
136 | this.load(this.pageUrl, params, this.setLoadedPage.createDelegate(this, [pageNum, callback]), | ||
137 | keepExisting ? (pageNum-1) * this.pageSize : null); | ||
138 | }, | ||
139 | |||
140 | /** @ignore */ | ||
141 | applySort: function(suppressEvent){ | ||
142 | if(!this.remoteSort){ | ||
143 | YAHOO.ext.grid.LoadableDataModel.superclass.applySort.apply(this, arguments); | ||
144 | }else if(!suppressEvent){ | ||
145 | var sort = this.getSortState(); | ||
146 | if(sort.column){ | ||
147 | this.fireRowsSorted(sort.column, sort.direction, true); | ||
148 | } | ||
149 | } | ||
150 | }, | ||
151 | |||
152 | /** @ignore */ | ||
153 | resetPaging: function(){ | ||
154 | this.loadedPage = 1; | ||
155 | }, | ||
156 | |||
157 | /* Overridden sort method to use remote sorting if turned on */ | ||
158 | sort: function(sortInfo, columnIndex, direction, suppressEvent){ | ||
159 | if(!this.remoteSort){ | ||
160 | YAHOO.ext.grid.LoadableDataModel.superclass.sort.apply(this, arguments); | ||
161 | }else{ | ||
162 | this.sortInfo = sortInfo; | ||
163 | this.sortColumn = columnIndex; | ||
164 | this.sortDir = direction; | ||
165 | var params = this.createParams(this.loadedPage, columnIndex, direction); | ||
166 | this.load(this.pageUrl, params, this.fireRowsSorted.createDelegate(this, [columnIndex, direction, true])); | ||
167 | } | ||
168 | }, | ||
169 | |||
170 | /** | ||
171 | * Initiates the loading of the data from the specified URL - Failed load attempts will | ||
172 | * fire the {@link #loadexception} event. | ||
173 | * @param {Object/String} url The url from which the data can be loaded | ||
174 | * @param {<i>String/Object</i>} params (optional) The parameters to pass as either a url encoded string "param1=1&param2=2" or as an object {param1: 1, param2: 2} | ||
175 | * @param {<i>Function</i>} callback (optional) Callback when load is complete - called with signature (this, true for success, false for failure) | ||
176 | * @param {<i>Number</i>} insertIndex (optional) if present, loaded data is inserted at the specified index instead of overwriting existing data | ||
177 | */ | ||
178 | load: function(url, params, callback, insertIndex){ | ||
179 | this.fireEvent('beforeload', this); | ||
180 | if(params && typeof params != 'string'){ // must be object | ||
181 | var buf = []; | ||
182 | for(var key in params){ | ||
183 | if(typeof params[key] != 'function'){ | ||
184 | buf.push(encodeURIComponent(key), '=', encodeURIComponent(params[key]), '&'); | ||
185 | } | ||
186 | } | ||
187 | delete buf[buf.length-1]; | ||
188 | params = buf.join(''); | ||
189 | } | ||
190 | var cb = { | ||
191 | success: this.processResponse, | ||
192 | failure: this.processException, | ||
193 | scope: this, | ||
194 | argument: {callback: callback, insertIndex: insertIndex} | ||
195 | }; | ||
196 | var method = params ? 'POST' : 'GET'; | ||
197 | this.transId = YAHOO.util.Connect.asyncRequest(method, url, cb, params); | ||
198 | }, | ||
199 | |||
200 | /**@private*/ | ||
201 | processResponse: function(response){ | ||
202 | var cb = response.argument.callback; | ||
203 | var keepExisting = (typeof response.argument.insertIndex == 'number'); | ||
204 | var insertIndex = response.argument.insertIndex; | ||
205 | switch(this.dataType){ | ||
206 | case YAHOO.ext.grid.LoadableDataModel.XML: | ||
207 | this.loadData(response.responseXML, cb, keepExisting, insertIndex); | ||
208 | break; | ||
209 | case YAHOO.ext.grid.LoadableDataModel.JSON: | ||
210 | var rtext = response.responseText; | ||
211 | try { // this code is a modified version of Yahoo! UI DataSource JSON parsing | ||
212 | // Trim leading spaces | ||
213 | while(rtext.substring(0,1) == " ") { | ||
214 | rtext = rtext.substring(1, rtext.length); | ||
215 | } | ||
216 | // Invalid JSON response | ||
217 | if(rtext.indexOf("{") < 0) { | ||
218 | throw "Invalid JSON response"; | ||
219 | } | ||
220 | |||
221 | // Empty (but not invalid) JSON response | ||
222 | if(rtext.indexOf("{}") === 0) { | ||
223 | this.loadData({}, response.argument.callback); | ||
224 | return; | ||
225 | } | ||
226 | |||
227 | // Turn the string into an object literal... | ||
228 | // ...eval is necessary here | ||
229 | var jsonObjRaw = eval("(" + rtext + ")"); | ||
230 | if(!jsonObjRaw) { | ||
231 | throw "Error evaling JSON response"; | ||
232 | } | ||
233 | this.loadData(jsonObjRaw, cb, keepExisting, insertIndex); | ||
234 | } catch(e) { | ||
235 | this.fireLoadException(e, response); | ||
236 | if(typeof cb == 'function'){ | ||
237 | cb(this, false); | ||
238 | } | ||
239 | } | ||
240 | break; | ||
241 | case YAHOO.ext.grid.LoadableDataModel.TEXT: | ||
242 | this.loadData(response.responseText, cb, keepExisting, insertIndex); | ||
243 | break; | ||
244 | }; | ||
245 | }, | ||
246 | |||
247 | /**@private*/ | ||
248 | processException: function(response){ | ||
249 | this.fireLoadException(null, response); | ||
250 | if(typeof response.argument.callback == 'function'){ | ||
251 | response.argument.callback(this, false); | ||
252 | } | ||
253 | }, | ||
254 | |||
255 | fireLoadException: function(e, responseObj){ | ||
256 | this.onLoadException.fireDirect(this, e, responseObj); | ||
257 | }, | ||
258 | |||
259 | fireLoadEvent: function(){ | ||
260 | this.fireEvent('load', this.loadedPage, this.getTotalPages()); | ||
261 | }, | ||
262 | |||
263 | /** | ||
264 | * Adds a preprocessor function to parse data before it is added to the Model - ie. Date.parse to parse dates. | ||
265 | * @param {Number} columnIndex | ||
266 | * @param {Function} fn | ||
267 | */ | ||
268 | addPreprocessor: function(columnIndex, fn){ | ||
269 | this.preprocessors[columnIndex] = fn; | ||
270 | }, | ||
271 | |||
272 | /** | ||
273 | * Gets the preprocessor function for the specified column. | ||
274 | * @param {Number} columnIndex | ||
275 | * @return {Function} | ||
276 | */ | ||
277 | getPreprocessor: function(columnIndex){ | ||
278 | return this.preprocessors[columnIndex]; | ||
279 | }, | ||
280 | |||
281 | /** | ||
282 | * Removes a preprocessor function. | ||
283 | * @param {Number} columnIndex | ||
284 | */ | ||
285 | removePreprocessor: function(columnIndex){ | ||
286 | this.preprocessors[columnIndex] = null; | ||
287 | }, | ||
288 | |||
289 | /** | ||
290 | * Adds a postprocessor function to format data before updating the underlying data source (ie. convert date to string before updating XML document). | ||
291 | * @param {Number} columnIndex | ||
292 | * @param {Function} fn | ||
293 | */ | ||
294 | addPostprocessor: function(columnIndex, fn){ | ||
295 | this.postprocessors[columnIndex] = fn; | ||
296 | }, | ||
297 | |||
298 | /** | ||
299 | * Gets the postprocessor function for the specified column. | ||
300 | * @param {Number} columnIndex | ||
301 | * @return {Function} | ||
302 | */ | ||
303 | getPostprocessor: function(columnIndex){ | ||
304 | return this.postprocessors[columnIndex]; | ||
305 | }, | ||
306 | |||
307 | /** | ||
308 | * Removes a postprocessor function. | ||
309 | * @param {Number} columnIndex | ||
310 | */ | ||
311 | removePostprocessor: function(columnIndex){ | ||
312 | this.postprocessors[columnIndex] = null; | ||
313 | }, | ||
314 | /** | ||
315 | * Empty interface method - Called to process the data returned by the XHR - Classes which extend LoadableDataModel should implement this method. | ||
316 | * See {@link YAHOO.ext.XMLDataModel} for an example implementation. | ||
317 | */ | ||
318 | loadData: function(data, callback, keepExisting, insertIndex){ | ||
319 | |||
320 | } | ||
321 | }); | ||
322 | |||
323 | YAHOO.ext.grid.LoadableDataModel.XML = 'xml'; | ||
324 | YAHOO.ext.grid.LoadableDataModel.JSON = 'json'; | ||
325 | YAHOO.ext.grid.LoadableDataModel.TEXT = 'text'; | ||
326 | |||
327 | |||
328 | |||
329 | |||
330 | |||