webgui/www/extras/yui/docs/autocomplete/overview-summary-DataSource.js.html
JT Smith 4f68a0933c added YUI and YUI-ext
fixed the resizable text area with IE problem
fixed the ad space with IE problem
merged the 7.2.0 and 7.1.4 change logs
2006-11-07 23:15:57 +00:00

1184 lines
52 KiB
HTML

<html>
<head>
<title>JavaScript Documentation - DataSource.js</title>
<link href="stylesheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header">
<h1>JavaScript Documentation</h1>
<h3><a href="./index.html">AutoComplete</a></h3>
<div class="breadcrumbs">
<a href="./index.html">AutoComplete</a>
&gt;
<strong>DataSource.js</strong>
</div>
</div>
<div id="body">
<div class="nav">
<div class="module resources">
<ul class="content">
<li><a href="overview-tree.html">Tree View</a></li>
<li><a href="index-all.html">Element Index</a></li>
</ul>
</div>
<div class="module">
<h4><a href="./allclasses-noframe.html">Classes</a></h4>
<ul class="content">
<li>
<a href="YAHOO.widget.html">
YAHOO.widget</a>
</li>
<li>
<a href="YAHOO.widget.AutoComplete.html">
YAHOO.widget.AutoComplete</a>
</li>
<li>
<a href="YAHOO.widget.DataSource.html">
YAHOO.widget.DataSource</a>
</li>
<li>
<a href="YAHOO.widget.DS_JSArray.html">
YAHOO.widget.DS_JSArray</a>
</li>
<li>
<a href="YAHOO.widget.DS_JSFunction.html">
YAHOO.widget.DS_JSFunction</a>
</li>
<li>
<a href="YAHOO.widget.DS_XHR.html">
YAHOO.widget.DS_XHR</a>
</li>
</ul>
</div>
<div class="module">
<h4><a href="./overview-summary.html">Files</a></h4>
<ul class="content">
<li>
<a href="overview-summary-AutoComplete.js.html">
AutoComplete.js</a>
</li>
<li>
<a href="overview-summary-DataSource.js.html">
DataSource.js</a>
</li>
</ul>
</div>
</div>
<div class="main">
<h2>DataSource.js</h2>
<div class="meta">
</div>
<div class="quick-links">
<strong>Quick Links:</strong>&nbsp;
<a href="#classSummary">Class Summary</a> |
<a href="#source">Source Code</a>
</div>
<div class="section class summaries">
<h3><a name="classSummary">Class Summary</a> <span class="top">[<a href="#top">top</a>]</span></h3>
<div class="content">
<table border="1" cellpadding="3" cellspacing="0">
<tr>
<td class="name">
<a href="YAHOO.widget.DS_XHR.html">YAHOO.widget.DS_XHR</a>
</td>
<td class="overview">&nbsp;</td>
</tr>
<tr>
<td class="name">
<a href="YAHOO.widget.DS_JSArray.html">YAHOO.widget.DS_JSArray</a>
</td>
<td class="overview">&nbsp;</td>
</tr>
<tr>
<td class="name">
<a href="YAHOO.widget.DS_JSFunction.html">YAHOO.widget.DS_JSFunction</a>
</td>
<td class="overview">&nbsp;</td>
</tr>
<tr>
<td class="name">
<a href="YAHOO.widget.DataSource.html">YAHOO.widget.DataSource</a>
</td>
<td class="overview">&nbsp;</td>
</tr>
</table>
</div>
</div>
<div class="section source">
<h3><a name="source">Souce Code</a> <span class="top">[<a href="#top">top</a>]</span></h3>
<pre class="sourceview"><span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/**
* Class providing encapsulation of a data source.
*
* <span class="attrib">@constructor</span>
*
*/</span>
YAHOO.widget.DataSource = <span class="reserved">function</span>() {
<span class="comment">/* abstract class */</span>
};
<span class="comment">/***************************************************************************
* Public constants
***************************************************************************/</span>
<span class="comment">/**
* Error message for null data responses.
*
* <span class="attrib">@type</span> constant
* <span class="attrib">@final</span>
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.ERROR_DATANULL = <span class="literal">"Response data was null"</span>;
<span class="comment">/**
* Error message for data responses with parsing errors.
*
* <span class="attrib">@type</span> constant
* <span class="attrib">@final</span>
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.ERROR_DATAPARSE = <span class="literal">"Response data could not be parsed"</span>;
<span class="comment">/***************************************************************************
* Public member variables
***************************************************************************/</span>
<span class="comment">/**
* Max size of the local cache. Set to 0 to turn off caching. Caching is
* useful to reduce the number of server connections. Recommended only for data
* sources that return comprehensive results for queries or when stale data is
* not an issue. Default: 15.
*
* <span class="attrib">@type</span> number
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.maxCacheEntries = 15;
<span class="comment">/**
* Use this to equate cache matching with the type of matching done by your live
* data source. If caching is on and queryMatchContains is true, the cache
* returns results that "contain" the query string. By default,
* queryMatchContains is set to false, meaning the cache only returns results
* that "start with" the query string. Default: false.
*
* <span class="attrib">@type</span> boolean
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.queryMatchContains = false;
<span class="comment">/**
* Data source query subset matching. If caching is on and queryMatchSubset is
* true, substrings of queries will return matching cached results. For
* instance, if the first query is for "abc" susequent queries that start with
* "abc", like "abcd", will be queried against the cache, and not the live data
* source. Recommended only for data sources that return comprehensive results
* for queries with very few characters. Default: false.
*
* <span class="attrib">@type</span> boolean
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.queryMatchSubset = false;
<span class="comment">/**
* Data source query case-sensitivity matching. If caching is on and
* queryMatchCase is true, queries will only return results for case-sensitive
* matches. Default: false.
*
* <span class="attrib">@type</span> boolean
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.queryMatchCase = false;
<span class="comment">/***************************************************************************
* Public methods
***************************************************************************/</span>
<span class="comment">/**
* Public accessor to the unique name of the data source instance.
*
* <span class="attrib">@return</span> {string} Unique name of the data source instance
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.toString = <span class="reserved">function</span>() {
<span class="reserved">return</span> <span class="literal">"DataSource "</span> + <span class="reserved">this</span>._sName;
};
<span class="comment">/**
* Retrieves query results, first checking the local cache, then making the
* query request to the live data source as defined by the function doQuery.
*
* <span class="attrib">@param</span> {object} oCallbackFn Callback function defined by oParent object to
* which to return results
* <span class="attrib">@param</span> {string} sQuery Query string
* <span class="attrib">@param</span> {object} oParent The object instance that has requested data
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.getResults = <span class="reserved">function</span>(oCallbackFn, sQuery, oParent) {
<span class="comment">
// First look in cache</span>
var aResults = <span class="reserved">this</span>._doQueryCache(oCallbackFn,sQuery,oParent);
<span class="comment">
// Not in cache, so get results from server</span>
<span class="reserved">if</span>(aResults.length === 0) {
<span class="reserved">this</span>.queryEvent.fire(<span class="reserved">this</span>, oParent, sQuery);
<span class="reserved">this</span>.doQuery(oCallbackFn, sQuery, oParent);
}
};
<span class="comment">/**
* Abstract method implemented by subclasses to make a query to the live data
* source. Must call the callback function with the response returned from the
* query. Populates cache (if enabled).
*
* <span class="attrib">@param</span> {object} oCallbackFn Callback function implemented by oParent to
* which to return results
* <span class="attrib">@param</span> {string} sQuery Query string
* <span class="attrib">@param</span> {object} oParent The object instance that has requested data
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.doQuery = <span class="reserved">function</span>(oCallbackFn, sQuery, oParent) {
<span class="comment">/* override this */</span>
};
<span class="comment">/**
* Flushes cache.
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.flushCache = <span class="reserved">function</span>() {
<span class="reserved">if</span>(<span class="reserved">this</span>._aCache) {
<span class="reserved">this</span>._aCache = [];
}
<span class="reserved">if</span>(<span class="reserved">this</span>._aCacheHelper) {
<span class="reserved">this</span>._aCacheHelper = [];
}
<span class="reserved">this</span>.cacheFlushEvent.fire(<span class="reserved">this</span>);
};
<span class="comment">/***************************************************************************
* Events
***************************************************************************/</span>
<span class="comment">/**
* Fired when a query is made to the live data source. Subscribers receive the
* following array:&lt;br&gt;
* - args[0] The data source instance
* - args[1] The requesting object
* - args[2] The query string
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.queryEvent = null;
<span class="comment">/**
* Fired when a query is made to the local cache. Subscribers receive the
* following array:&lt;br&gt;
* - args[0] The data source instance
* - args[1] The requesting object
* - args[2] The query string
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.cacheQueryEvent = null;
<span class="comment">/**
* Fired when data is retrieved from the live data source. Subscribers receive
* the following array:&lt;br&gt;
* - args[0] The data source instance
* - args[1] The requesting object
* - args[2] The query string
* - args[3] Array of result objects
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.getResultsEvent = null;
<span class="comment">/**
* Fired when data is retrieved from the local cache. Subscribers receive the
* following array :&lt;br&gt;
* - args[0] The data source instance
* - args[1] The requesting object
* - args[2] The query string
* - args[3] Array of result objects
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.getCachedResultsEvent = null;
<span class="comment">/**
* Fired when an error is encountered with the live data source. Subscribers
* receive the following array:&lt;br&gt;
* - args[0] The data source instance
* - args[1] The requesting object
* - args[2] The query string
* - args[3] Error message string
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.dataErrorEvent = null;
<span class="comment">/**
* Fired when the local cache is flushed. Subscribers receive the following
* array :&lt;br&gt;
* - args[0] The data source instance
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>.cacheFlushEvent = null;
<span class="comment">/***************************************************************************
* Private member variables
***************************************************************************/</span>
<span class="comment">/**
* Internal class variable to index multiple data source instances.
*
* <span class="attrib">@type</span> number
* <span class="attrib">@private</span>
*/</span>
YAHOO.widget.DataSource._nIndex = 0;
<span class="comment">/**
* Name of data source instance.
*
* <span class="attrib">@type</span> string
* <span class="attrib">@private</span>
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>._sName = null;
<span class="comment">/**
* Local cache of data result objects indexed chronologically.
*
* <span class="attrib">@type</span> array
* <span class="attrib">@private</span>
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>._aCache = null;
<span class="comment">/***************************************************************************
* Private methods
***************************************************************************/</span>
<span class="comment">/**
* Initializes data source instance.
*
* <span class="attrib">@private</span>
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>._init = <span class="reserved">function</span>() {
<span class="comment"> // Validate and initialize public configs</span>
var maxCacheEntries = <span class="reserved">this</span>.maxCacheEntries;
<span class="reserved">if</span>(isNaN(maxCacheEntries) || (maxCacheEntries &lt; 0)) {
maxCacheEntries = 0;
}
<span class="comment"> // Initialize local cache</span>
<span class="reserved">if</span>(maxCacheEntries &gt; 0 &amp;&amp; !<span class="reserved">this</span>._aCache) {
<span class="reserved">this</span>._aCache = [];
}
<span class="reserved">this</span>._sName = <span class="literal">"instance"</span> + YAHOO.widget.DataSource._nIndex;
YAHOO.widget.DataSource._nIndex++;
<span class="reserved">this</span>.queryEvent = new YAHOO.util.CustomEvent(<span class="literal">"query"</span>, <span class="reserved">this</span>);
<span class="reserved">this</span>.cacheQueryEvent = new YAHOO.util.CustomEvent(<span class="literal">"cacheQuery"</span>, <span class="reserved">this</span>);
<span class="reserved">this</span>.getResultsEvent = new YAHOO.util.CustomEvent(<span class="literal">"getResults"</span>, <span class="reserved">this</span>);
<span class="reserved">this</span>.getCachedResultsEvent = new YAHOO.util.CustomEvent(<span class="literal">"getCachedResults"</span>, <span class="reserved">this</span>);
<span class="reserved">this</span>.dataErrorEvent = new YAHOO.util.CustomEvent(<span class="literal">"dataError"</span>, <span class="reserved">this</span>);
<span class="reserved">this</span>.cacheFlushEvent = new YAHOO.util.CustomEvent(<span class="literal">"cacheFlush"</span>, <span class="reserved">this</span>);
};
<span class="comment">/**
* Adds a result object to the local cache, evicting the oldest element if the
* cache is full. Newer items will have higher indexes, the oldest item will have
* index of 0.
*
* <span class="attrib">@param</span> {object} resultObj Object literal of data results, including internal
* properties and an array of result objects
* <span class="attrib">@private</span>
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>._addCacheElem = <span class="reserved">function</span>(resultObj) {
var aCache = <span class="reserved">this</span>._aCache;
<span class="comment"> // Don't add if anything important is missing.</span>
<span class="reserved">if</span>(!aCache || !resultObj || !resultObj.query || !resultObj.results) {
<span class="reserved">return</span>;
}
<span class="comment">
// If the cache is full, make room by removing from index=0</span>
<span class="reserved">if</span>(aCache.length &gt;= <span class="reserved">this</span>.maxCacheEntries) {
aCache.shift();
}
<span class="comment">
// Add to cache, at the end of the array</span>
aCache.push(resultObj);
};
<span class="comment">/**
* Queries the local cache for results. If query has been cached, the callback
* function is called with the results, and the cached is refreshed so that it
* is now the newest element.
*
* <span class="attrib">@param</span> {object} oCallbackFn Callback function defined by oParent object to
* which to return results
* <span class="attrib">@param</span> {string} sQuery Query string
* <span class="attrib">@param</span> {object} oParent The object instance that has requested data
* <span class="attrib">@return</span> {array} aResults Result object from local cache if found, otherwise
* null
* <span class="attrib">@private</span>
*/</span>
YAHOO.widget.DataSource.<span class="reserved">prototype</span>._doQueryCache = <span class="reserved">function</span>(oCallbackFn, sQuery, oParent) {
var aResults = [];
var bMatchFound = false;
var aCache = <span class="reserved">this</span>._aCache;
var nCacheLength = (aCache) ? aCache.length : 0;
var bMatchContains = <span class="reserved">this</span>.queryMatchContains;
<span class="comment">
// If cache is enabled...</span>
<span class="reserved">if</span>((<span class="reserved">this</span>.maxCacheEntries &gt; 0) &amp;&amp; aCache &amp;&amp; (nCacheLength &gt; 0)) {
<span class="reserved">this</span>.cacheQueryEvent.fire(<span class="reserved">this</span>, oParent, sQuery);
<span class="comment"> // If case is unimportant, normalize query now instead of in loops</span>
<span class="reserved">if</span>(!<span class="reserved">this</span>.queryMatchCase) {
var sOrigQuery = sQuery;
sQuery = sQuery.toLowerCase();
}
<span class="comment">
// Loop through each cached element's query property...</span>
<span class="reserved">for</span>(var i = nCacheLength-1; i &gt;= 0; i--) {
var resultObj = aCache[i];
var aAllResultItems = resultObj.results;
<span class="comment"> // If case is unimportant, normalize match key for comparison</span>
var matchKey = (!<span class="reserved">this</span>.queryMatchCase) ?
encodeURIComponent(resultObj.query.toLowerCase()):
encodeURIComponent(resultObj.query);
<span class="comment">
// If a cached match key exactly matches the query...</span>
<span class="reserved">if</span>(matchKey == sQuery) {
<span class="comment"> // Stash all result objects into aResult[] and stop looping through the cache.</span>
bMatchFound = true;
aResults = aAllResultItems;
<span class="comment">
// The matching cache element was not the most recent,</span>
<span class="comment"> // so now we need to refresh the cache.</span>
<span class="reserved">if</span>(i != nCacheLength-1) {
<span class="comment"> // Remove element from its original location</span>
aCache.splice(i,1);
<span class="comment"> // Add element as newest</span>
<span class="reserved">this</span>._addCacheElem(resultObj);
}
break;
}
<span class="comment"> // Else if this query is not an exact match and subset matching is enabled...</span>
<span class="reserved">else</span> <span class="reserved">if</span>(<span class="reserved">this</span>.queryMatchSubset) {
<span class="comment"> // Loop through substrings of each cached element's query property...</span>
<span class="reserved">for</span>(var j = sQuery.length-1; j &gt;= 0 ; j--) {
var subQuery = sQuery.substr(0,j);
<span class="comment">
// If a substring of a cached sQuery exactly matches the query...</span>
<span class="reserved">if</span>(matchKey == subQuery) {
bMatchFound = true;
<span class="comment">
// Go through each cached result object to match against the query...</span>
<span class="reserved">for</span>(var k = aAllResultItems.length-1; k &gt;= 0; k--) {
var aRecord = aAllResultItems[k];
var sKeyIndex = (<span class="reserved">this</span>.queryMatchCase) ?
encodeURIComponent(aRecord[0]).indexOf(sQuery):
encodeURIComponent(aRecord[0]).toLowerCase().indexOf(sQuery);
<span class="comment">
// A STARTSWITH match is when the query is found at the beginning of the key string...</span>
<span class="reserved">if</span>((!bMatchContains &amp;&amp; (sKeyIndex === 0)) ||
<span class="comment"> // A CONTAINS match is when the query is found anywhere within the key string...</span>
(bMatchContains &amp;&amp; (sKeyIndex &gt; -1))) {
<span class="comment"> // Stash a match into aResults[].</span>
aResults.unshift(aRecord);
}
}
<span class="comment">
// Add the subset match result set object as the newest element to cache,</span>
<span class="comment"> // and stop looping through the cache.</span>
resultObj = {};
resultObj.query = sQuery;
resultObj.results = aResults;
<span class="reserved">this</span>._addCacheElem(resultObj);
break;
}
}
<span class="reserved">if</span>(bMatchFound) {
break;
}
}
}
<span class="comment">
// If there was a match, send along the results.</span>
<span class="reserved">if</span>(bMatchFound) {
<span class="reserved">this</span>.getCachedResultsEvent.fire(<span class="reserved">this</span>, oParent, sOrigQuery, aResults);
oCallbackFn(sOrigQuery, aResults, oParent);
}
}
<span class="reserved">return</span> aResults;
};
<span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/**
* Implementation of YAHOO.widget.DataSource using XML HTTP requests that return
* query results.
* requires YAHOO.util.Connect XMLHTTPRequest library
* extends YAHOO.widget.DataSource
*
* <span class="attrib">@constructor</span>
* <span class="attrib">@param</span> {string} sScriptURI Absolute or relative URI to script that returns
* query results as JSON, XML, or delimited flat data
* <span class="attrib">@param</span> {array} aSchema Data schema definition of results
* <span class="attrib">@param</span> {object} oConfigs Optional object literal of config params
*/</span>
YAHOO.widget.DS_XHR = <span class="reserved">function</span>(sScriptURI, aSchema, oConfigs) {
<span class="comment"> // Set any config params passed in to override defaults</span>
<span class="reserved">if</span>(typeof oConfigs == <span class="literal">"object"</span>) {
<span class="reserved">for</span>(var sConfig in oConfigs) {
<span class="reserved">this</span>[sConfig] = oConfigs[sConfig];
}
}
<span class="comment">
// Initialization sequence</span>
<span class="reserved">if</span>(!aSchema || (aSchema.constructor != Array)) {
YAHOO.log(<span class="literal">"Could not instantiate XHR DataSource due to invalid arguments"</span>, <span class="literal">"error"</span>, <span class="reserved">this</span>.toString());
<span class="reserved">return</span>;
}
<span class="reserved">else</span> {
<span class="reserved">this</span>.schema = aSchema;
}
<span class="reserved">this</span>.scriptURI = sScriptURI;
<span class="reserved">this</span>._init();
YAHOO.log(<span class="literal">"XHR DataSource initialized"</span>,<span class="literal">"info"</span>,<span class="reserved">this</span>.toString());
};
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span> = new YAHOO.widget.DataSource();
<span class="comment">/***************************************************************************
* Public constants
***************************************************************************/</span>
<span class="comment">/**
* JSON data type
*
* <span class="attrib">@type</span> constant
* <span class="attrib">@final</span>
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.TYPE_JSON = 0;
<span class="comment">/**
* XML data type
*
* <span class="attrib">@type</span> constant
* <span class="attrib">@final</span>
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.TYPE_XML = 1;
<span class="comment">/**
* Flat file data type
*
* <span class="attrib">@type</span> constant
* <span class="attrib">@final</span>
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.TYPE_FLAT = 2;
<span class="comment">/**
* Error message for XHR failure.
*
* <span class="attrib">@type</span> constant
* <span class="attrib">@final</span>
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.ERROR_DATAXHR = <span class="literal">"XHR response failed"</span>;
<span class="comment">/***************************************************************************
* Public member variables
***************************************************************************/</span>
<span class="comment">/**
* Number of milliseconds the XHR connection will wait for a server response. A
* a value of zero indicates the XHR connection will wait forever. Any value
* greater than zero will use the Connection utility's Auto-Abort feature.
* Default: 0.
*
* <span class="attrib">@type</span> number
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.connTimeout = 0;
<span class="comment">/**
* Absolute or relative URI to script that returns query results. For instance,
* queries will be sent to
* &lt;scriptURI&gt;?&lt;scriptQueryParam&gt;=userinput
*
* <span class="attrib">@type</span> string
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.scriptURI = null;
<span class="comment">/**
* Query string parameter name sent to scriptURI. For instance, queries will be
* sent to
* &lt;scriptURI&gt;?&lt;scriptQueryParam&gt;=userinput
* Default: "query".
*
* <span class="attrib">@type</span> string
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.scriptQueryParam = <span class="literal">"query"</span>;
<span class="comment">/**
* String of key/value pairs to append to requests made to scriptURI. Define
* this string when you want to send additional query parameters to your script.
* When defined, queries will be sent to
* &lt;scriptURI&gt;?&lt;scriptQueryParam&gt;=userinput&amp;&lt;scriptQueryAppend&gt;
* Default: "".
*
* <span class="attrib">@type</span> string
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.scriptQueryAppend = <span class="literal">""</span>;
<span class="comment">/**
* XHR response data type. Other types that may be defined are TYPE_XML and
* TYPE_FLAT. Default: TYPE_JSON.
*
* <span class="attrib">@type</span> type
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.responseType = YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.TYPE_JSON;
<span class="comment">/**
* String after which to strip results. If the results from the XHR are sent
* back as HTML, the gzip HTML comment appears at the end of the data and should
* be ignored. Default: "\n&amp;lt;!--"
*
* <span class="attrib">@type</span> string
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.responseStripAfter = <span class="literal">"\n&lt;!--"</span>;
<span class="comment">/***************************************************************************
* Public methods
***************************************************************************/</span>
<span class="comment">/**
* Queries the live data source defined by scriptURI for results. Results are
* passed back to a callback function.
*
* <span class="attrib">@param</span> {object} oCallbackFn Callback function defined by oParent object to
* which to return results
* <span class="attrib">@param</span> {string} sQuery Query string
* <span class="attrib">@param</span> {object} oParent The object instance that has requested data
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.doQuery = <span class="reserved">function</span>(oCallbackFn, sQuery, oParent) {
var isXML = (<span class="reserved">this</span>.responseType == <span class="reserved">this</span>.TYPE_XML);
var sUri = <span class="reserved">this</span>.scriptURI+<span class="literal">"?"</span>+<span class="reserved">this</span>.scriptQueryParam+<span class="literal">"="</span>+sQuery;
<span class="reserved">if</span>(<span class="reserved">this</span>.scriptQueryAppend.length &gt; 0) {
sUri += <span class="literal">"&amp;"</span> + <span class="reserved">this</span>.scriptQueryAppend;
}
YAHOO.log(<span class="literal">"Data source is querying URL "</span> + sUri, <span class="literal">"info"</span>, <span class="reserved">this</span>.toString());
var oResponse = null;
var oSelf = <span class="reserved">this</span>;
<span class="comment">/**
* Sets up ajax request callback
*
* <span class="attrib">@param</span> {object} oReq HTTPXMLRequest object
* <span class="attrib">@private</span>
*/</span>
var responseSuccess = <span class="reserved">function</span>(oResp) {
<span class="comment"> // Response ID does not match last made request ID.</span>
<span class="reserved">if</span>(!oSelf._oConn || (oResp.tId != oSelf._oConn.tId)) {
oSelf.dataErrorEvent.fire(oSelf, oParent, sQuery, oSelf.ERROR_DATANULL);
YAHOO.log(oSelf.ERROR_DATANULL, <span class="literal">"error"</span>, <span class="reserved">this</span>.toString());
<span class="reserved">return</span>;
}
<span class="comment">//DEBUG</span>
<span class="comment">/*YAHOO.log(oResp.responseXML.getElementsByTagName("Result"),'warn');
for(var foo in oResp) {
YAHOO.log(foo + ": "+oResp[foo],'warn');
}
YAHOO.log('responseXML.xml: '+oResp.responseXML.xml,'warn');*/</span>
<span class="reserved">if</span>(!isXML) {
oResp = oResp.responseText;
}
<span class="reserved">else</span> {
oResp = oResp.responseXML;
}
<span class="reserved">if</span>(oResp === null) {
oSelf.dataErrorEvent.fire(oSelf, oParent, sQuery, oSelf.ERROR_DATANULL);
YAHOO.log(oSelf.ERROR_DATANULL, <span class="literal">"error"</span>, oSelf.toString());
<span class="reserved">return</span>;
}
var aResults = oSelf.parseResponse(sQuery, oResp, oParent);
var resultObj = {};
resultObj.query = decodeURIComponent(sQuery);
resultObj.results = aResults;
<span class="reserved">if</span>(aResults === null) {
oSelf.dataErrorEvent.fire(oSelf, oParent, sQuery, oSelf.ERROR_DATAPARSE);
YAHOO.log(oSelf.ERROR_DATAPARSE, <span class="literal">"error"</span>, oSelf.toString());
<span class="reserved">return</span>;
}
<span class="reserved">else</span> {
oSelf.getResultsEvent.fire(oSelf, oParent, sQuery, aResults);
oSelf._addCacheElem(resultObj);
oCallbackFn(sQuery, aResults, oParent);
}
};
var responseFailure = <span class="reserved">function</span>(oResp) {
oSelf.dataErrorEvent.fire(oSelf, oParent, sQuery, oSelf.ERROR_DATAXHR);
YAHOO.log(oSelf.ERROR_DATAXHR + <span class="literal">": "</span> + oResp.statusText, <span class="literal">"error"</span>, oSelf.toString());
<span class="reserved">return</span>;
};
var oCallback = {
success:responseSuccess,
failure:responseFailure
};
<span class="reserved">if</span>(!isNaN(<span class="reserved">this</span>.connTimeout) &amp;&amp; <span class="reserved">this</span>.connTimeout &gt; 0) {
oCallback.timeout = <span class="reserved">this</span>.connTimeout;
}
<span class="reserved">if</span>(<span class="reserved">this</span>._oConn) {
YAHOO.util.Connect.abort(<span class="reserved">this</span>._oConn);
}
oSelf._oConn = YAHOO.util.Connect.asyncRequest(<span class="literal">"GET"</span>, sUri, oCallback, null);
};
<span class="comment">/**
* Parses raw response data into an array of result objects. The result data key
* is always stashed in the [0] element of each result object.
*
* <span class="attrib">@param</span> {string} sQuery Query string
* <span class="attrib">@param</span> {object} oResponse The raw response data to parse
* <span class="attrib">@param</span> {object} oParent The object instance that has requested data
* <span class="attrib">@returns</span> {array} Array of result objects
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>.parseResponse = <span class="reserved">function</span>(sQuery, oResponse, oParent) {
var aSchema = <span class="reserved">this</span>.schema;
var aResults = [];
var bError = false;
<span class="comment">
// Strip out comment at the end of results</span>
var nEnd = ((<span class="reserved">this</span>.responseStripAfter !== <span class="literal">""</span>) &amp;&amp; (oResponse.indexOf)) ?
oResponse.indexOf(<span class="reserved">this</span>.responseStripAfter) : -1;
<span class="reserved">if</span>(nEnd != -1) {
oResponse = oResponse.substring(0,nEnd);
}
switch (this.responseType) {
case this.TYPE_JSON:
var jsonList;
if(window.JSON) {
// Use the JSON utility if available
var jsonObjParsed = JSON.parse(oResponse);
if(!jsonObjParsed) {
bError = true;
break;
}
else {
// eval is necessary here since aSchema[0] is of unknown depth
jsonList = eval("jsonObjParsed." + aSchema[0]);
}
}
else {
// Parse the JSON response as a string
try {
// Trim leading spaces
while (oResponse.substring(0,1) == " ") {
oResponse = oResponse.substring(1, oResponse.length);
}
// Invalid JSON response
if(oResponse.indexOf("{") &lt; 0) {
bError = true;
break;
}
// Empty (but not invalid) JSON response
if(oResponse.indexOf("{}") === 0) {
break;
}
// Turn the string into an object literal...
// ...eval is necessary here
var jsonObjRaw = eval("(" + oResponse + ")");
if(!jsonObjRaw) {
bError = true;
break;
}
// Grab the object member that contains an array of all reponses...
// ...eval is necessary here since aSchema[0] is of unknown depth
jsonList = eval("(jsonObjRaw." + aSchema[0]+")");
}
catch(e) {
bError = true;
break;
}
}
if(!jsonList) {
bError = true;
break;
}
// Loop through the array of all responses...
for(var i = jsonList.length-1; i &gt;= 0 ; i--) {
var aResultItem = [];
var jsonResult = jsonList[i];
// ...and loop through each data field value of each response
for(var j = aSchema.length-1; j &gt;= 1 ; j--) {
// ...and capture data into an array mapped according to the schema...
var dataFieldValue = jsonResult[aSchema[j]];
if(!dataFieldValue) {
dataFieldValue = "";
}
//YAHOO.log("data: " + i + " value:" +j+" = "+dataFieldValue,"debug",this.toString());
aResultItem.unshift(dataFieldValue);
}
// Capture the array of data field values in an array of results
aResults.unshift(aResultItem);
}
break;
case this.TYPE_XML:
// Get the collection of results
var xmlList = oResponse.getElementsByTagName(aSchema[0]);
if(!xmlList) {
bError = true;
break;
}
// Loop through each result
for(var k = xmlList.length-1; k &gt;= 0 ; k--) {
var result = xmlList.item(k);
//YAHOO.log("Result"+k+" is "+result.attributes.item(0).firstChild.nodeValue,"debug",this.toString());
var aFieldSet = [];
// Loop through each data field in each result using the schema
for(var m = aSchema.length-1; m &gt;= 1 ; m--) {
//YAHOO.log(aSchema[m]+" is "+result.attributes.getNamedItem(aSchema[m]).firstChild.nodeValue);
var sValue = null;
// Values may be held in an attribute...
var xmlAttr = result.attributes.getNamedItem(aSchema[m]);
if(xmlAttr) {
sValue = xmlAttr.value;
//YAHOO.log("Attr value is "+sValue,"debug",this.toString());
}
// ...or in a node
else{
var xmlNode = result.getElementsByTagName(aSchema[m]);
if(xmlNode &amp;&amp; xmlNode.item(0) &amp;&amp; xmlNode.item(0).firstChild) {
sValue = xmlNode.item(0).firstChild.nodeValue;
//YAHOO.log("Node value is "+sValue,"debug",this.toString());
}
else {
sValue = "";
//YAHOO.log("Value not found","debug",this.toString());
}
}
// Capture the schema-mapped data field values into an array
aFieldSet.unshift(sValue);
}
// Capture each array of values into an array of results
aResults.unshift(aFieldSet);
}
break;
case this.TYPE_FLAT:
if(oResponse.length &gt; 0) {
// Delete the last line delimiter at the end of the data if it exists
var newLength = oResponse.length-aSchema[0].length;
if(oResponse.substr(newLength) == aSchema[0]) {
oResponse = oResponse.substr(0, newLength);
}
var aRecords = oResponse.split(aSchema[0]);
for(var n = aRecords.length-1; n &gt;= 0; n--) {
aResults[n] = aRecords[n].split(aSchema[1]);
}
}
break;
default:
break;
}>
<span class="reserved">if</span>(bError) {
<span class="reserved">return</span> null;
}
<span class="reserved">else</span> {
<span class="reserved">return</span> aResults;
}
};
<span class="comment">/***************************************************************************
* Private member variables
***************************************************************************/</span>
<span class="comment">/**
* XHR connection object.
*
* <span class="attrib">@type</span> object
* <span class="attrib">@private</span>
*/</span>
YAHOO.widget.DS_XHR.<span class="reserved">prototype</span>._oConn = null;
<span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/**
* Implementation of YAHOO.widget.DataSource using a native Javascript struct as
* its live data source.
*
* <span class="attrib">@constructor</span>
* extends YAHOO.widget.DataSource
*
* <span class="attrib">@param</span> {string} oFunction In-memory Javascript function that returns query
* results as an array of objects
* <span class="attrib">@param</span> {object} oConfigs Optional object literal of config params
*/</span>
YAHOO.widget.DS_JSFunction = <span class="reserved">function</span>(oFunction, oConfigs) {
<span class="comment"> // Set any config params passed in to override defaults</span>
<span class="reserved">if</span>(typeof oConfigs == <span class="literal">"object"</span>) {
<span class="reserved">for</span>(var sConfig in oConfigs) {
<span class="reserved">this</span>[sConfig] = oConfigs[sConfig];
}
}
<span class="comment">
// Initialization sequence</span>
<span class="reserved">if</span>(!oFunction || (oFunction.constructor != Function)) {
YAHOO.log(<span class="literal">"Could not instantiate JSFunction DataSource due to invalid arguments"</span>, <span class="literal">"error"</span>, <span class="reserved">this</span>.toString());
<span class="reserved">return</span>;
}
<span class="reserved">else</span> {
<span class="reserved">this</span>.dataFunction = oFunction;
<span class="reserved">this</span>._init();
YAHOO.log(<span class="literal">"JS Function DataSource initialized"</span>,<span class="literal">"info"</span>,<span class="reserved">this</span>.toString());
}
};
YAHOO.widget.DS_JSFunction.<span class="reserved">prototype</span> = new YAHOO.widget.DataSource();
<span class="comment">/***************************************************************************
* Public member variables
***************************************************************************/</span>
<span class="comment">/**
* In-memory Javascript function that returns query results.
*
* <span class="attrib">@type</span> function
*/</span>
YAHOO.widget.DS_JSFunction.<span class="reserved">prototype</span>.dataFunction = null;
<span class="comment">/***************************************************************************
* Public methods
***************************************************************************/</span>
<span class="comment">/**
* Queries the live data source defined by function for results. Results are
* passed back to a callback function.
*
* <span class="attrib">@param</span> {object} oCallbackFn Callback function defined by oParent object to
* which to return results
* <span class="attrib">@param</span> {string} sQuery Query string
* <span class="attrib">@param</span> {object} oParent The object instance that has requested data
*/</span>
YAHOO.widget.DS_JSFunction.<span class="reserved">prototype</span>.doQuery = <span class="reserved">function</span>(oCallbackFn, sQuery, oParent) {
var oFunction = <span class="reserved">this</span>.dataFunction;
var aResults = [];
aResults = oFunction(sQuery);
<span class="reserved">if</span>(aResults === null) {
<span class="reserved">this</span>.dataErrorEvent.fire(<span class="reserved">this</span>, oParent, sQuery, <span class="reserved">this</span>.ERROR_DATANULL);
YAHOO.log(oSelf.ERROR_DATANULL, <span class="literal">"error"</span>, <span class="reserved">this</span>.toString());
<span class="reserved">return</span>;
}
var resultObj = {};
resultObj.query = decodeURIComponent(sQuery);
resultObj.results = aResults;
<span class="reserved">this</span>._addCacheElem(resultObj);
<span class="reserved">this</span>.getResultsEvent.fire(<span class="reserved">this</span>, oParent, sQuery, aResults);
oCallbackFn(sQuery, aResults, oParent);
<span class="reserved">return</span>;
};
<span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/****************************************************************************/</span>
<span class="comment">/**
* Implementation of YAHOO.widget.DataSource using a native Javascript array as
* its live data source.
*
* <span class="attrib">@constructor</span>
* extends YAHOO.widget.DataSource
*
* <span class="attrib">@param</span> {string} aData In-memory Javascript array of simple string data
* <span class="attrib">@param</span> {object} oConfigs Optional object literal of config params
*/</span>
YAHOO.widget.DS_JSArray = <span class="reserved">function</span>(aData, oConfigs) {
<span class="comment"> // Set any config params passed in to override defaults</span>
<span class="reserved">if</span>(typeof oConfigs == <span class="literal">"object"</span>) {
<span class="reserved">for</span>(var sConfig in oConfigs) {
<span class="reserved">this</span>[sConfig] = oConfigs[sConfig];
}
}
<span class="comment">
// Initialization sequence</span>
<span class="reserved">if</span>(!aData || (aData.constructor != Array)) {
YAHOO.log(<span class="literal">"Could not instantiate JSArray DataSource due to invalid arguments"</span>, <span class="literal">"error"</span>, <span class="reserved">this</span>.toString());
<span class="reserved">return</span>;
}
<span class="reserved">else</span> {
<span class="reserved">this</span>.data = aData;
<span class="reserved">this</span>._init();
YAHOO.log(<span class="literal">"JS Array DataSource initialized"</span>,<span class="literal">"info"</span>,<span class="reserved">this</span>.toString());
}
};
YAHOO.widget.DS_JSArray.<span class="reserved">prototype</span> = new YAHOO.widget.DataSource();
<span class="comment">/***************************************************************************
* Public member variables
***************************************************************************/</span>
<span class="comment">/**
* In-memory Javascript array of strings.
*
* <span class="attrib">@type</span> array
*/</span>
YAHOO.widget.DS_JSArray.<span class="reserved">prototype</span>.data = null;
<span class="comment">/***************************************************************************
* Public methods
***************************************************************************/</span>
<span class="comment">/**
* Queries the live data source defined by data for results. Results are passed
* back to a callback function.
*
* <span class="attrib">@param</span> {object} oCallbackFn Callback function defined by oParent object to
* which to return results
* <span class="attrib">@param</span> {string} sQuery Query string
* <span class="attrib">@param</span> {object} oParent The object instance that has requested data
*/</span>
YAHOO.widget.DS_JSArray.<span class="reserved">prototype</span>.doQuery = <span class="reserved">function</span>(oCallbackFn, sQuery, oParent) {
var aData = <span class="reserved">this</span>.data;
var aResults = [];
var bMatchFound = false;
var bMatchContains = <span class="reserved">this</span>.queryMatchContains;
<span class="reserved">if</span>(!<span class="reserved">this</span>.queryMatchCase) {
sQuery = sQuery.toLowerCase();
}
<span class="comment">
// Loop through each element of the array...</span>
<span class="reserved">for</span>(var i = aData.length-1; i &gt;= 0; i--) {
var aDataset = [];
<span class="reserved">if</span>(typeof aData[i] == <span class="literal">"string"</span>) {
aDataset[0] = aData[i];
}
<span class="reserved">else</span> {
aDataset = aData[i];
}
var sKeyIndex = (<span class="reserved">this</span>.queryMatchCase) ?
encodeURIComponent(aDataset[0]).indexOf(sQuery):
encodeURIComponent(aDataset[0]).toLowerCase().indexOf(sQuery);
<span class="comment">
// A STARTSWITH match is when the query is found at the beginning of the key string...</span>
<span class="reserved">if</span>((!bMatchContains &amp;&amp; (sKeyIndex === 0)) ||
<span class="comment"> // A CONTAINS match is when the query is found anywhere within the key string...</span>
(bMatchContains &amp;&amp; (sKeyIndex &gt; -1))) {
<span class="comment"> // Stash a match into aResults[].</span>
aResults.unshift(aDataset);
}
}
<span class="reserved">this</span>.getResultsEvent.fire(<span class="reserved">this</span>, oParent, sQuery, aResults);
oCallbackFn(sQuery, aResults, oParent);
};
</pre>
</div>
</div>
</div>
<div id="footer">
<hr />
Copyright &copy; 2006 Yahoo! Inc. All rights reserved.
<br />
Documentation generated by <a href="http://jsdoc.sourceforge.net/">JSDoc</a>
</div>
</body>
</html>