]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojox/data/HtmlTableStore.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / data / HtmlTableStore.js
1 if(!dojo._hasResource["dojox.data.HtmlTableStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.data.HtmlTableStore"] = true;
3 dojo.provide("dojox.data.HtmlTableStore");
4
5 dojo.require("dojox.data.dom");
6 dojo.require("dojo.data.util.simpleFetch");
7 dojo.require("dojo.data.util.filter");
8
9 dojo.declare("dojox.data.HtmlTableStore", null, {
10         constructor: function(/*Object*/args){
11                 dojo.deprecated("dojox.data.HtmlTableStore", "Please use dojox.data.HtmlStore");
12                 //      summary:
13                 //              Initializer for the HTML table store.  
14                 //      description:
15                 //              The HtmlTableStore can be created in one of two ways: a) by parsing an existing
16                 //              table DOM node on the current page or b) by referencing an external url and giving
17                 //              the id of the table in that page.  The remote url will be parsed as an html page.
18                 //
19                 //              The HTML table should be of the following form:
20                 //              <table id="myTable">
21                 //                      <thead>
22                 //                              <tr>
23                 //                                      <th>Attribute1</th>
24                 //                                      <th>Attribute2</th>
25                 //                              </tr>
26                 //                      </thead>
27                 //                      <tbody>
28                 //                              <tr>
29                 //                                      <td>Value1.1</td>
30                 //                                      <td>Value1.2</td>
31                 //                              </tr>
32                 //                              <tr>
33                 //                                      <td>Value2.1</td>
34                 //                                      <td>Value2.2</td>
35                 //                              </tr>
36                 //                      </tbody>
37                 //              </table>
38                 //
39                 //      args:
40                 //              An anonymous object to initialize properties.  It expects the following values:
41                 //              tableId:        The id of the HTML table to use.
42                 //              OR
43                 //              url:            The url of the remote page to load
44                 //              tableId:        The id of the table element in the remote page
45                 
46                 if(args.url){
47                         if(!args.tableId)
48                                 throw new Error("dojo.data.HtmlTableStore: Cannot instantiate using url without an id!");
49                         this.url = args.url;
50                         this.tableId = args.tableId;
51                 }else{
52                         if(args.tableId){
53                                 this._rootNode = dojo.byId(args.tableId);
54                                 this.tableId = this._rootNode.id;
55                         }else{
56                                 this._rootNode = dojo.byId(this.tableId);
57                         }
58                         this._getHeadings();
59                         for(var i=0; i<this._rootNode.rows.length; i++){
60                                 this._rootNode.rows[i].store = this;
61                         }
62                 }
63         },
64
65         url: "",     // So the parser can instantiate the store via markup.
66         tableId: "", // So the parser can instantiate the store via markup.
67
68         _getHeadings: function(){
69                 //      summary:
70                 //              Function to load the attribute names from the table header so that the 
71                 //              attributes (cells in a row), can have a reasonable name.
72                 this._headings = [];
73                 dojo.forEach(this._rootNode.tHead.rows[0].cells, dojo.hitch(this, function(th){
74                         this._headings.push(dojox.data.dom.textContent(th));
75                 }));
76         },
77         
78         _getAllItems: function(){
79                 //      summary:
80                 //              Function to return all rows in the table as an array of items.
81                 var items = [];
82                 for(var i=1; i<this._rootNode.rows.length; i++){
83                         items.push(this._rootNode.rows[i]);
84                 }
85                 return items; //array
86         },
87         
88         _assertIsItem: function(/* item */ item){
89                 //      summary:
90                 //      This function tests whether the item passed in is indeed an item in the store.
91                 //      item: 
92                 //              The item to test for being contained by the store.
93                 if(!this.isItem(item)){ 
94                         throw new Error("dojo.data.HtmlTableStore: a function was passed an item argument that was not an item");
95                 }
96         },
97
98         _assertIsAttribute: function(/* String */ attribute){
99                 //      summary:
100                 //      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
101                 //      attribute: 
102                 //              The attribute to test for being contained by the store.
103                 //
104                 //      returns:
105                 //              Returns the index (column) that the attribute resides in the row.
106                 if(typeof attribute !== "string"){ 
107                         throw new Error("dojo.data.HtmlTableStore: a function was passed an attribute argument that was not an attribute name string");
108                         return -1;
109                 }
110                 return dojo.indexOf(this._headings, attribute); //int
111         },
112
113 /***************************************
114      dojo.data.api.Read API
115 ***************************************/
116         
117         getValue: function(     /* item */ item, 
118                                                 /* attribute-name-string */ attribute, 
119                                                 /* value? */ defaultValue){
120                 //      summary: 
121                 //      See dojo.data.api.Read.getValue()
122                 var values = this.getValues(item, attribute);
123                 return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean
124         },
125
126         getValues: function(/* item */ item, 
127                                                 /* attribute-name-string */ attribute){
128                 //      summary: 
129                 //              See dojo.data.api.Read.getValues()
130
131                 this._assertIsItem(item);
132                 var index = this._assertIsAttribute(attribute);
133
134                 if(index>-1){
135                         return [dojox.data.dom.textContent(item.cells[index])] ;
136                 }
137                 return []; //Array
138         },
139
140         getAttributes: function(/* item */ item){
141                 //      summary: 
142                 //              See dojo.data.api.Read.getAttributes()
143                 this._assertIsItem(item);
144                 var attributes = [];
145                 for(var i=0; i<this._headings.length; i++){
146                         if(this.hasAttribute(item, this._headings[i]))
147                                 attributes.push(this._headings[i]);
148                 }
149                 return attributes; //Array
150         },
151
152         hasAttribute: function( /* item */ item,
153                                                         /* attribute-name-string */ attribute){
154                 //      summary: 
155                 //              See dojo.data.api.Read.hasAttribute()
156                 return this.getValues(item, attribute).length > 0;
157         },
158
159         containsValue: function(/* item */ item, 
160                                                         /* attribute-name-string */ attribute, 
161                                                         /* anything */ value){
162                 //      summary: 
163                 //              See dojo.data.api.Read.containsValue()
164                 var regexp = undefined;
165                 if(typeof value === "string"){
166                    regexp = dojo.data.util.filter.patternToRegExp(value, false);
167                 }
168                 return this._containsValue(item, attribute, value, regexp); //boolean.
169         },
170
171         _containsValue: function(       /* item */ item, 
172                                                                 /* attribute-name-string */ attribute, 
173                                                                 /* anything */ value,
174                                                                 /* RegExp?*/ regexp){
175                 //      summary: 
176                 //              Internal function for looking at the values contained by the item.
177                 //      description: 
178                 //              Internal function for looking at the values contained by the item.  This 
179                 //              function allows for denoting if the comparison should be case sensitive for
180                 //              strings or not (for handling filtering cases where string case should not matter)
181                 //      
182                 //      item:
183                 //              The data item to examine for attribute values.
184                 //      attribute:
185                 //              The attribute to inspect.
186                 //      value:  
187                 //              The value to match.
188                 //      regexp:
189                 //              Optional regular expression generated off value if value was of string type to handle wildcarding.
190                 //              If present and attribute values are string, then it can be used for comparison instead of 'value'
191                 var values = this.getValues(item, attribute);
192                 for(var i = 0; i < values.length; ++i){
193                         var possibleValue = values[i];
194                         if(typeof possibleValue === "string" && regexp){
195                                 return (possibleValue.match(regexp) !== null);
196                         }else{
197                                 //Non-string matching.
198                                 if(value === possibleValue){
199                                         return true; // Boolean
200                                 }
201                         }
202                 }
203                 return false; // Boolean
204         },
205
206         isItem: function(/* anything */ something){
207                 //      summary: 
208                 //              See dojo.data.api.Read.isItem()
209                 if(something && something.store && something.store === this){
210                         return true; //boolean
211                 }
212                 return false; //boolean
213         },
214
215         isItemLoaded: function(/* anything */ something){
216                 //      summary: 
217                 //              See dojo.data.api.Read.isItemLoaded()
218                 return this.isItem(something);
219         },
220
221         loadItem: function(/* Object */ keywordArgs){
222                 //      summary: 
223                 //              See dojo.data.api.Read.loadItem()
224                 this._assertIsItem(keywordArgs.item);
225         },
226         
227         _fetchItems: function(request, fetchHandler, errorHandler) {
228                 //      summary:
229                 //              Fetch items (XML elements) that match to a query
230                 //      description:
231                 //              If '_fetchUrl' is specified, it is used to load an XML document
232                 //              with a query string.
233                 //              Otherwise and if 'url' is specified, the XML document is
234                 //              loaded and list XML elements that match to a query (set of element
235                 //              names and their text attribute values that the items to contain).
236                 //              A wildcard, "*" can be used to query values to match all
237                 //              occurrences.
238                 //              If '_rootItem' is specified, it is used to fetch items.
239                 //      request:
240                 //              A request object
241                 //      fetchHandler:
242                 //              A function to call for fetched items
243                 //      errorHandler:
244                 //              A function to call on error
245                 
246                 if(this._rootNode){
247                         this._finishFetchItems(request, fetchHandler, errorHandler);
248                 }else{
249                         if(!this.url){
250                                 this._rootNode = dojo.byId(this.tableId);
251                                 this._getHeadings();
252                                 for(var i=0; i<this._rootNode.rows.length; i++){
253                                         this._rootNode.rows[i].store = this;
254                                 }
255                         }else{
256                                 var getArgs = {
257                                                 url: this.url,
258                                                 handleAs: "text"
259                                         };
260                                 var self = this;
261                                 var getHandler = dojo.xhrGet(getArgs);
262                                 getHandler.addCallback(function(data){
263                                         var findNode = function(node, id){
264                                                 if(node.id == id){
265                                                         return node; //object
266                                                 }
267                                                 if(node.childNodes){
268                                                         for(var i=0; i<node.childNodes.length; i++){
269                                                                 var returnNode = findNode(node.childNodes[i], id);
270                                                                 if(returnNode){
271                                                                         return returnNode; //object
272                                                                 }
273                                                         }
274                                                 }
275                                                 return null; //null
276                                         }
277
278                                         var d = document.createElement("div");
279                                         d.innerHTML = data;
280                                         self._rootNode = findNode(d, self.tableId);
281                                         self._getHeadings.call(self);
282                                         for(var i=0; i<self._rootNode.rows.length; i++) {
283                                                 self._rootNode.rows[i].store = self;
284                                         }
285                                         self._finishFetchItems(request, fetchHandler, errorHandler);
286                                 });
287                                 getHandler.addErrback(function(error){
288                                         errorHandler(error, request);
289                                 });
290                         }
291                 }
292         },
293         
294         _finishFetchItems: function(request, fetchHandler, errorHandler){
295                 //      summary:
296                 //              Internal function for processing the passed in request and locating the requested items.
297                 var items = null;
298                 var arrayOfAllItems = this._getAllItems();
299                 if(request.query){
300                         var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false; 
301                         items = [];
302
303                         //See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
304                         //same value for each item examined.  Much more efficient.
305                         var regexpList = {};
306                         var value;
307                         var key;
308                         for(key in request.query){
309                                 value = request.query[key]+'';
310                                 if(typeof value === "string"){
311                                         regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
312                                 }
313                         }
314
315                         for(var i = 0; i < arrayOfAllItems.length; ++i){
316                                 var match = true;
317                                 var candidateItem = arrayOfAllItems[i];
318                                 for(key in request.query){
319                                         value = request.query[key]+'';
320                                         if (!this._containsValue(candidateItem, key, value, regexpList[key])){
321                                                 match = false;
322                                         }
323                                 }
324                                 if(match){
325                                         items.push(candidateItem);
326                                 }
327                         }
328                         fetchHandler(items, request);
329                 }else{
330                         // We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort 
331                         // of the internal list so that multiple callers can get listsand sort without affecting each other.
332                         if(arrayOfAllItems.length> 0){
333                                 items = arrayOfAllItems.slice(0,arrayOfAllItems.length); 
334                         }
335                         fetchHandler(items, request);
336                 }
337         },
338
339         getFeatures: function(){
340                 //      summary: 
341                 //              See dojo.data.api.Read.getFeatures()
342                 return {
343                         'dojo.data.api.Read': true,
344                         'dojo.data.api.Identity': true
345                 };
346         },
347         
348         close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
349                 //      summary:
350                 //              See dojo.data.api.Read.close()
351                 // nothing to do here!
352         },
353
354         getLabel: function(/* item */ item){
355                 //      summary: 
356                 //              See dojo.data.api.Read.getLabel()
357                 if(this.isItem(item))
358                         return "Table Row #" + this.getIdentity(item);
359                 return undefined;
360         },
361
362         getLabelAttributes: function(/* item */ item){
363                 //      summary: 
364                 //              See dojo.data.api.Read.getLabelAttributes()
365                 return null;
366         },
367
368 /***************************************
369      dojo.data.api.Identity API
370 ***************************************/
371
372         getIdentity: function(/* item */ item){
373                 //      summary: 
374                 //              See dojo.data.api.Identity.getIdentity()
375                 this._assertIsItem(item);
376                 //Opera doesn't support the sectionRowIndex, 
377                 //So, have to call the indexOf to locate it. 
378                 //Blah.
379                 if(!dojo.isOpera){
380                         return item.sectionRowIndex; // int     
381                 }else{
382                         return (dojo.indexOf(this._rootNode.rows, item) - 1) // int
383                 }
384         },
385
386         getIdentityAttributes: function(/* item */ item){
387                  //     summary: 
388                  //             See dojo.data.api.Identity.getIdentityAttributes()
389                  //Identity isn't taken from a public attribute.
390                  return null;
391         },
392
393         fetchItemByIdentity: function(keywordArgs){
394                 //      summary: 
395                 //              See dojo.data.api.Identity.fetchItemByIdentity()
396                 var identity = keywordArgs.identity;
397                 var self = this;
398                 var item = null;
399                 var scope = null;
400
401                 if(!this._rootNode){
402                         if(!this.url){
403                                 this._rootNode = dojo.byId(this.tableId);
404                                 this._getHeadings();
405                                 for(var i=0; i<this._rootNode.rows.length; i++){
406                                         this._rootNode.rows[i].store = this;
407                                 }
408                                 item = this._rootNode.rows[identity+1];
409                                 if (keywordArgs.onItem){
410                                         scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
411                                         keywordArgs.onItem.call(scope, item);
412                                 }
413
414                         }else{
415                                 var getArgs = {
416                                                 url: this.url,
417                                                 handleAs: "text"
418                                         };
419                                 var getHandler = dojo.xhrGet(getArgs);
420                                 getHandler.addCallback(function(data){
421                                         var findNode = function(node, id){
422                                                 if(node.id == id){
423                                                         return node; //object
424                                                 }
425                                                 if(node.childNodes) {
426                                                         for(var i=0; i<node.childNodes.length; i++){
427                                                                 var returnNode = findNode(node.childNodes[i], id);
428                                                                 if(returnNode){
429                                                                         return returnNode; //object
430                                                                 }
431                                                         }
432                                                 }
433                                                 return null; //null
434                                         }
435                                         var d = document.createElement("div");
436                                         d.innerHTML = data;
437                                         self._rootNode = findNode(d, self.tableId);
438                                         self._getHeadings.call(self);
439                                         for(var i=0; i<self._rootNode.rows.length; i++){
440                                                 self._rootNode.rows[i].store = self;
441                                         }
442                                         item = self._rootNode.rows[identity+1];
443                                         if (keywordArgs.onItem){
444                                                 scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
445                                                 keywordArgs.onItem.call(scope, item);
446                                         }
447                                 });
448                                 getHandler.addErrback(function(error){
449                                         if(keywordArgs.onError){
450                                                 scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
451                                                 keywordArgs.onError.call(scope, error);
452
453                                         }
454                                 });
455                         }
456                 }else{
457                         if(this._rootNode.rows[identity+1]){
458                                 item = this._rootNode.rows[identity+1];
459                                 if (keywordArgs.onItem){
460                                         scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
461                                         keywordArgs.onItem.call(scope, item);
462                                 }
463                         }
464                 }
465         }
466 });
467 dojo.extend(dojox.data.HtmlTableStore,dojo.data.util.simpleFetch);
468
469 }