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");
5 dojo.require("dojox.data.dom");
6 dojo.require("dojo.data.util.simpleFetch");
7 dojo.require("dojo.data.util.filter");
9 dojo.declare("dojox.data.HtmlTableStore", null, {
10 constructor: function(/*Object*/args){
11 dojo.deprecated("dojox.data.HtmlTableStore", "Please use dojox.data.HtmlStore");
13 // Initializer for the HTML table store.
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.
19 // The HTML table should be of the following form:
20 // <table id="myTable">
23 // <th>Attribute1</th>
24 // <th>Attribute2</th>
40 // An anonymous object to initialize properties. It expects the following values:
41 // tableId: The id of the HTML table to use.
43 // url: The url of the remote page to load
44 // tableId: The id of the table element in the remote page
48 throw new Error("dojo.data.HtmlTableStore: Cannot instantiate using url without an id!");
50 this.tableId = args.tableId;
53 this._rootNode = dojo.byId(args.tableId);
54 this.tableId = this._rootNode.id;
56 this._rootNode = dojo.byId(this.tableId);
59 for(var i=0; i<this._rootNode.rows.length; i++){
60 this._rootNode.rows[i].store = this;
65 url: "", // So the parser can instantiate the store via markup.
66 tableId: "", // So the parser can instantiate the store via markup.
68 _getHeadings: function(){
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.
73 dojo.forEach(this._rootNode.tHead.rows[0].cells, dojo.hitch(this, function(th){
74 this._headings.push(dojox.data.dom.textContent(th));
78 _getAllItems: function(){
80 // Function to return all rows in the table as an array of items.
82 for(var i=1; i<this._rootNode.rows.length; i++){
83 items.push(this._rootNode.rows[i]);
88 _assertIsItem: function(/* item */ item){
90 // This function tests whether the item passed in is indeed an item in the store.
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");
98 _assertIsAttribute: function(/* String */ attribute){
100 // This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
102 // The attribute to test for being contained by the store.
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");
110 return dojo.indexOf(this._headings, attribute); //int
113 /***************************************
114 dojo.data.api.Read API
115 ***************************************/
117 getValue: function( /* item */ item,
118 /* attribute-name-string */ attribute,
119 /* value? */ defaultValue){
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
126 getValues: function(/* item */ item,
127 /* attribute-name-string */ attribute){
129 // See dojo.data.api.Read.getValues()
131 this._assertIsItem(item);
132 var index = this._assertIsAttribute(attribute);
135 return [dojox.data.dom.textContent(item.cells[index])] ;
140 getAttributes: function(/* item */ item){
142 // See dojo.data.api.Read.getAttributes()
143 this._assertIsItem(item);
145 for(var i=0; i<this._headings.length; i++){
146 if(this.hasAttribute(item, this._headings[i]))
147 attributes.push(this._headings[i]);
149 return attributes; //Array
152 hasAttribute: function( /* item */ item,
153 /* attribute-name-string */ attribute){
155 // See dojo.data.api.Read.hasAttribute()
156 return this.getValues(item, attribute).length > 0;
159 containsValue: function(/* item */ item,
160 /* attribute-name-string */ attribute,
161 /* anything */ value){
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);
168 return this._containsValue(item, attribute, value, regexp); //boolean.
171 _containsValue: function( /* item */ item,
172 /* attribute-name-string */ attribute,
173 /* anything */ value,
174 /* RegExp?*/ regexp){
176 // Internal function for looking at the values contained by the item.
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)
183 // The data item to examine for attribute values.
185 // The attribute to inspect.
187 // The value to match.
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);
197 //Non-string matching.
198 if(value === possibleValue){
199 return true; // Boolean
203 return false; // Boolean
206 isItem: function(/* anything */ something){
208 // See dojo.data.api.Read.isItem()
209 if(something && something.store && something.store === this){
210 return true; //boolean
212 return false; //boolean
215 isItemLoaded: function(/* anything */ something){
217 // See dojo.data.api.Read.isItemLoaded()
218 return this.isItem(something);
221 loadItem: function(/* Object */ keywordArgs){
223 // See dojo.data.api.Read.loadItem()
224 this._assertIsItem(keywordArgs.item);
227 _fetchItems: function(request, fetchHandler, errorHandler) {
229 // Fetch items (XML elements) that match to a query
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
238 // If '_rootItem' is specified, it is used to fetch items.
242 // A function to call for fetched items
244 // A function to call on error
247 this._finishFetchItems(request, fetchHandler, errorHandler);
250 this._rootNode = dojo.byId(this.tableId);
252 for(var i=0; i<this._rootNode.rows.length; i++){
253 this._rootNode.rows[i].store = this;
261 var getHandler = dojo.xhrGet(getArgs);
262 getHandler.addCallback(function(data){
263 var findNode = function(node, id){
265 return node; //object
268 for(var i=0; i<node.childNodes.length; i++){
269 var returnNode = findNode(node.childNodes[i], id);
271 return returnNode; //object
278 var d = document.createElement("div");
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;
285 self._finishFetchItems(request, fetchHandler, errorHandler);
287 getHandler.addErrback(function(error){
288 errorHandler(error, request);
294 _finishFetchItems: function(request, fetchHandler, errorHandler){
296 // Internal function for processing the passed in request and locating the requested items.
298 var arrayOfAllItems = this._getAllItems();
300 var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false;
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.
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);
315 for(var i = 0; i < arrayOfAllItems.length; ++i){
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])){
325 items.push(candidateItem);
328 fetchHandler(items, request);
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);
335 fetchHandler(items, request);
339 getFeatures: function(){
341 // See dojo.data.api.Read.getFeatures()
343 'dojo.data.api.Read': true,
344 'dojo.data.api.Identity': true
348 close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
350 // See dojo.data.api.Read.close()
351 // nothing to do here!
354 getLabel: function(/* item */ item){
356 // See dojo.data.api.Read.getLabel()
357 if(this.isItem(item))
358 return "Table Row #" + this.getIdentity(item);
362 getLabelAttributes: function(/* item */ item){
364 // See dojo.data.api.Read.getLabelAttributes()
368 /***************************************
369 dojo.data.api.Identity API
370 ***************************************/
372 getIdentity: function(/* item */ item){
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.
380 return item.sectionRowIndex; // int
382 return (dojo.indexOf(this._rootNode.rows, item) - 1) // int
386 getIdentityAttributes: function(/* item */ item){
388 // See dojo.data.api.Identity.getIdentityAttributes()
389 //Identity isn't taken from a public attribute.
393 fetchItemByIdentity: function(keywordArgs){
395 // See dojo.data.api.Identity.fetchItemByIdentity()
396 var identity = keywordArgs.identity;
403 this._rootNode = dojo.byId(this.tableId);
405 for(var i=0; i<this._rootNode.rows.length; i++){
406 this._rootNode.rows[i].store = this;
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);
419 var getHandler = dojo.xhrGet(getArgs);
420 getHandler.addCallback(function(data){
421 var findNode = function(node, id){
423 return node; //object
425 if(node.childNodes) {
426 for(var i=0; i<node.childNodes.length; i++){
427 var returnNode = findNode(node.childNodes[i], id);
429 return returnNode; //object
435 var d = document.createElement("div");
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;
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);
448 getHandler.addErrback(function(error){
449 if(keywordArgs.onError){
450 scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
451 keywordArgs.onError.call(scope, error);
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);
467 dojo.extend(dojox.data.HtmlTableStore,dojo.data.util.simpleFetch);