Blame | Last modification | View Log | RSS feed
if(!dojo._hasResource["dojox.data.HtmlTableStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.dojo._hasResource["dojox.data.HtmlTableStore"] = true;dojo.provide("dojox.data.HtmlTableStore");dojo.require("dojox.data.dom");dojo.require("dojo.data.util.simpleFetch");dojo.require("dojo.data.util.filter");dojo.declare("dojox.data.HtmlTableStore", null, {constructor: function(/*Object*/args){// summary:// Initializer for the HTML table store.// description:// The HtmlTableStore can be created in one of two ways: a) by parsing an existing// table DOM node on the current page or b) by referencing an external url and giving// the id of the table in that page. The remote url will be parsed as an html page.//// The HTML table should be of the following form:// <table id="myTable">// <thead>// <tr>// <th>Attribute1</th>// <th>Attribute2</th>// </tr>// </thead>// <tbody>// <tr>// <td>Value1.1</td>// <td>Value1.2</td>// </tr>// <tr>// <td>Value2.1</td>// <td>Value2.2</td>// </tr>// </tbody>// </table>//// args:// An anonymous object to initialize properties. It expects the following values:// tableId: The id of the HTML table to use.// OR// url: The url of the remote page to load// tableId: The id of the table element in the remote pageif(args.url){if(!args.tableId)throw new Error("dojo.data.HtmlTableStore: Cannot instantiate using url without an id!");this.url = args.url;this.tableId = args.tableId;}else{if(args.tableId){this._rootNode = dojo.byId(args.tableId);this.tableId = this._rootNode.id;}else{this._rootNode = dojo.byId(this.tableId);}this._getHeadings();for(var i=0; i<this._rootNode.rows.length; i++){this._rootNode.rows[i].store = this;}}},url: "", // So the parser can instantiate the store via markup.tableId: "", // So the parser can instantiate the store via markup._getHeadings: function(){// summary:// Function to load the attribute names from the table header so that the// attributes (cells in a row), can have a reasonable name.this._headings = [];dojo.forEach(this._rootNode.tHead.rows[0].cells, dojo.hitch(this, function(th){this._headings.push(dojox.data.dom.textContent(th));}));},_getAllItems: function(){// summary:// Function to return all rows in the table as an array of items.var items = [];for(var i=1; i<this._rootNode.rows.length; i++){items.push(this._rootNode.rows[i]);}return items; //array},_assertIsItem: function(/* item */ item){// summary:// This function tests whether the item passed in is indeed an item in the store.// item:// The item to test for being contained by the store.if(!this.isItem(item)){throw new Error("dojo.data.HtmlTableStore: a function was passed an item argument that was not an item");}},_assertIsAttribute: function(/* String */ attribute){// summary:// This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.// attribute:// The attribute to test for being contained by the store.//// returns:// Returns the index (column) that the attribute resides in the row.if(typeof attribute !== "string"){throw new Error("dojo.data.HtmlTableStore: a function was passed an attribute argument that was not an attribute name string");return;}return dojo.indexOf(this._headings, attribute); //int},/***************************************dojo.data.api.Read API***************************************/getValue: function( /* item */ item,/* attribute-name-string */ attribute,/* value? */ defaultValue){// summary:// See dojo.data.api.Read.getValue()var values = this.getValues(item, attribute);return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean},getValues: function(/* item */ item,/* attribute-name-string */ attribute){// summary:// See dojo.data.api.Read.getValues()this._assertIsItem(item);var index = this._assertIsAttribute(attribute);if(index>-1){return [dojox.data.dom.textContent(item.cells[index])] ;}return []; //Array},getAttributes: function(/* item */ item){// summary:// See dojo.data.api.Read.getAttributes()this._assertIsItem(item);var attributes = [];for(var i=0; i<this._headings.length; i++){if(this.hasAttribute(item, this._headings[i]))attributes.push(this._headings[i]);}return attributes; //Array},hasAttribute: function( /* item */ item,/* attribute-name-string */ attribute){// summary:// See dojo.data.api.Read.hasAttribute()return this.getValues(item, attribute).length > 0;},containsValue: function(/* item */ item,/* attribute-name-string */ attribute,/* anything */ value){// summary:// See dojo.data.api.Read.containsValue()var regexp = undefined;if(typeof value === "string"){regexp = dojo.data.util.filter.patternToRegExp(value, false);}return this._containsValue(item, attribute, value, regexp); //boolean.},_containsValue: function( /* item */ item,/* attribute-name-string */ attribute,/* anything */ value,/* RegExp?*/ regexp){// summary:// Internal function for looking at the values contained by the item.// description:// Internal function for looking at the values contained by the item. This// function allows for denoting if the comparison should be case sensitive for// strings or not (for handling filtering cases where string case should not matter)//// item:// The data item to examine for attribute values.// attribute:// The attribute to inspect.// value:// The value to match.// regexp:// Optional regular expression generated off value if value was of string type to handle wildcarding.// If present and attribute values are string, then it can be used for comparison instead of 'value'var values = this.getValues(item, attribute);for(var i = 0; i < values.length; ++i){var possibleValue = values[i];if(typeof possibleValue === "string" && regexp){return (possibleValue.match(regexp) !== null);}else{//Non-string matching.if(value === possibleValue){return true; // Boolean}}}return false; // Boolean},isItem: function(/* anything */ something){// summary:// See dojo.data.api.Read.isItem()if(something && something.store && something.store === this){return true; //boolean}return false; //boolean},isItemLoaded: function(/* anything */ something){// summary:// See dojo.data.api.Read.isItemLoaded()return this.isItem(something);},loadItem: function(/* Object */ keywordArgs){// summary:// See dojo.data.api.Read.loadItem()this._assertIsItem(keywordArgs.item);},_fetchItems: function(request, fetchHandler, errorHandler) {// summary:// Fetch items (XML elements) that match to a query// description:// If '_fetchUrl' is specified, it is used to load an XML document// with a query string.// Otherwise and if 'url' is specified, the XML document is// loaded and list XML elements that match to a query (set of element// names and their text attribute values that the items to contain).// A wildcard, "*" can be used to query values to match all// occurrences.// If '_rootItem' is specified, it is used to fetch items.// request:// A request object// fetchHandler:// A function to call for fetched items// errorHandler:// A function to call on errorif(this._rootNode){this._finishFetchItems(request, fetchHandler, errorHandler);}else{if(!this.url){this._rootNode = dojo.byId(this.tableId);this._getHeadings();for(var i=0; i<this._rootNode.rows.length; i++){this._rootNode.rows[i].store = this;}}else{var getArgs = {url: this.url,handleAs: "text"};var self = this;var getHandler = dojo.xhrGet(getArgs);getHandler.addCallback(function(data){var findNode = function(node, id){if(node.id == id){return node; //object}if(node.childNodes){for(var i=0; i<node.childNodes.length; i++){var returnNode = findNode(node.childNodes[i], id);if(returnNode){return returnNode; //object}}}return null; //null}var d = document.createElement("div");d.innerHTML = data;self._rootNode = findNode(d, self.tableId);self._getHeadings.call(self);for(var i=0; i<self._rootNode.rows.length; i++) {self._rootNode.rows[i].store = self;}self._finishFetchItems(request, fetchHandler, errorHandler);});getHandler.addErrback(function(error){errorHandler(error, request);});}}},_finishFetchItems: function(request, fetchHandler, errorHandler){// summary:// Internal function for processing the passed in request and locating the requested items.var items = null;var arrayOfAllItems = this._getAllItems();if(request.query){var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false;items = [];//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the//same value for each item examined. Much more efficient.var regexpList = {};for(var key in request.query){var value = request.query[key]+'';if(typeof value === "string"){regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);}}for(var i = 0; i < arrayOfAllItems.length; ++i){var match = true;var candidateItem = arrayOfAllItems[i];for(var key in request.query){var value = request.query[key]+'';if (!this._containsValue(candidateItem, key, value, regexpList[key])){match = false;}}if(match){items.push(candidateItem);}}fetchHandler(items, request);}else{// We want a copy to pass back in case the parent wishes to sort the array. We shouldn't allow resort// of the internal list so that multiple callers can get listsand sort without affecting each other.if(arrayOfAllItems.length> 0){items = arrayOfAllItems.slice(0,arrayOfAllItems.length);}fetchHandler(items, request);}},getFeatures: function(){// summary:// See dojo.data.api.Read.getFeatures()return {'dojo.data.api.Read': true,'dojo.data.api.Identity': true};},close: function(/*dojo.data.api.Request || keywordArgs || null */ request){// summary:// See dojo.data.api.Read.close()// nothing to do here!},getLabel: function(/* item */ item){// summary:// See dojo.data.api.Read.getLabel()if(this.isItem(item))return "Table Row #" + this.getIdentity(item);return undefined;},getLabelAttributes: function(/* item */ item){// summary:// See dojo.data.api.Read.getLabelAttributes()return null;},/***************************************dojo.data.api.Identity API***************************************/getIdentity: function(/* item */ item){// summary:// See dojo.data.api.Identity.getIdentity()this._assertIsItem(item);//Opera doesn't support the sectionRowIndex,//So, have to call the indexOf to locate it.//Blah.if(!dojo.isOpera){return item.sectionRowIndex; // int}else{return (dojo.indexOf(this._rootNode.rows, item) - 1) // int}},getIdentityAttributes: function(/* item */ item){// summary:// See dojo.data.api.Identity.getIdentityAttributes()//Identity isn't taken from a public attribute.return null;},fetchItemByIdentity: function(keywordArgs){// summary:// See dojo.data.api.Identity.fetchItemByIdentity()var identity = keywordArgs.identity;var self = this;var item = nullif(!this._rootNode){if(!this.url){this._rootNode = dojo.byId(this.tableId);this._getHeadings();for(var i=0; i<this._rootNode.rows.length; i++){this._rootNode.rows[i].store = this;}item = this._rootNode.rows[identity+1];if (keywordArgs.onItem){var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;keywordArgs.onItem.call(scope, item);}}else{var getArgs = {url: this.url,handleAs: "text"};var self = this;var getHandler = dojo.xhrGet(getArgs);getHandler.addCallback(function(data){var findNode = function(node, id){if(node.id == id){return node; //object}if(node.childNodes) {for(var i=0; i<node.childNodes.length; i++){var returnNode = findNode(node.childNodes[i], id);if(returnNode){return returnNode; //object}}}return null; //null}var d = document.createElement("div");d.innerHTML = data;self._rootNode = findNode(d, self.tableId);self._getHeadings.call(self);for(var i=0; i<self._rootNode.rows.length; i++){self._rootNode.rows[i].store = self;}item = self._rootNode.rows[identity+1];if (keywordArgs.onItem){var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;keywordArgs.onItem.call(scope, item);}});getHandler.addErrback(function(error){if(keywordArgs.onError){var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;keywordArgs.onError.call(scope, error);}});}}else{if(this._rootNode.rows[identity+1]){item = this._rootNode.rows[identity+1];if (keywordArgs.onItem){var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;keywordArgs.onItem.call(scope, item);}}}}});dojo.extend(dojox.data.HtmlTableStore,dojo.data.util.simpleFetch);}