JavaChap Blog Java and Technology musings for the masses

1Jul/091

YUI Components with DWR – DWR DataSource

I'm working on project which uses YUI and DWR. The hardest part is intergrating these two. I googled on how people integrated YUI and DWR, found this and this. But these solutions will only work with earlier versions of YUI. I'm using YUI 2.7. So i ended up writing my own DWRDataSource. Might be useful for guys who want to integrate DWR and YUI 2.7.

Drawbacks :

  • This version unlike XHRDataSource does not support queuing and aborting the requests, as DWR has no support for aborting the requests.
  • No support to call java methods which has multiple arguments. Eg: You cannot invoke UserService.getUser(name, email).
YAHOO.namespace("javachap.util");
javachap = YAHOO.javachap;

var DS = YAHOO.util.DataSourceBase,
	lang = YAHOO.lang;

javachap.util.DWRDataSource = function(oLiveData, oConfigs) {
    this.dataType = DS.TYPE_XHR;
    oLiveData = oLiveData || "";

    javachap.util.DWRDataSource.superclass.constructor.call(this, oLiveData, oConfigs);
};

//DWRDataSource extends DataSourceBase
YAHOO.lang.extend(javachap.util.DWRDataSource, DS, {
	/**
	 * Overriding method passes query to Connection Manager. The returned
	 * response is then forwarded to the handleResponse function.
	 *
	 * @method makeConnection
	 * @param oRequest {Object} Request object.
	 * @param oCallback {Object} Callback object literal.
	 * @param oCaller {Object} (deprecated) Use oCallback.scope.
	 * @return {Number} Transaction ID.
	 */
	makeConnection : function(oRequest, oCallback, oCaller) {
	    var oRawResponse = null;
	    var tId = DS._nTransactionId++;
	    this.fireEvent("requestEvent", {tId:tId,request:oRequest,callback:oCallback,caller:oCaller});

	    // Set up the callback object and
	    var oSelf = this;

	    /**
	     * Define DWR success handler
	     *
	     * @method _dwrSuccess
	     * @param oResponse {Object} DWR Response
	     * @private
	     */
	    var _dwrSuccess = function(oResponse) {
	        // If response ID does not match last made request ID,
	        // silently fail and wait for the next response
	        if(oResponse && (this.connXhrMode == "ignoreStaleResponses") &&
	                (oResponse.tId != oQueue.conn.tId)) {
	            YAHOO.log("Ignored stale response", "warn", this.toString());
	            return null;
	        }
	        // Error if no response
	        else if(!oResponse) {
	        	oSelf.fireEvent("dataErrorEvent", {request:oRequest,
	                    callback:oCallback, caller:oCaller,
	                    message:DS.ERROR_DATANULL});
	            YAHOO.log(DS.ERROR_DATANULL, "error", this.toString());

	            // Send error response back to the caller with the error flag on
	            DS.issueCallback(oCallback, [oRequest, {error:true}], true, oCaller);

	            return null;
	        }
	        // Forward to handler
	        else {
	            //oSelf.responseType = DS.TYPE_JSARRAY;
	            // Try to sniff data type if it has not been defined
	            if(oSelf.responseType === DS.TYPE_UNKNOWN) {
	                if(YAHOO.lang.isArray(oResponse)) { // array
	                	oSelf.responseType = DS.TYPE_JSARRAY;
	                }
	                 // xml
	                else if(oResponse && oResponse.nodeType && oResponse.nodeType == 9) {
	                	oSelf.responseType = DS.TYPE_XML;
	                }
	                else if(oResponse && oRawResponse.nodeName && (oResponse.nodeName.toLowerCase() == "table")) { // table
	                	oSelf.responseType = DS.TYPE_HTMLTABLE;
	                }
	                else if(YAHOO.lang.isObject(oResponse)) { // json
	                	oSelf.responseType = DS.TYPE_JSON;
	                }
	                else if(YAHOO.lang.isString(oResponse)) { // text
	                	oSelf.responseType = DS.TYPE_TEXT;
	                }
	            }
	            oSelf.handleResponse(oRequest, oResponse, oCallback, oCaller, tId);
	        }
	    };

	    /**
	     * Define DWR failure handler
	     *
	     * @method _dwrFailure
	     * @param oResponse {Object} Exception object
	     * @private
	     */
	    var _dwrFailure = function(oResponse) {
	        this.fireEvent("dataErrorEvent", {request:oRequest,
	                callback:oCallback, caller:oCaller,
	                message:DS.ERROR_DATAINVALID});
	        YAHOO.log(DS.ERROR_DATAINVALID + ": " +
	                oResponse.statusText, "error", this.toString());

	        // Send failure response back to the caller with the error flag on
	        oResponse = oResponse || {};
	        oResponse.error = true;
	        DS.issueCallback(oCallback, [oRequest,oResponse], true, oCaller);

	        return null;
	    };

	    /**
	     * Define DWR call meta data
	     *
	     * @property _dwrCallMetaData
	     * @private
	     */
	     var _dwrCallMetaData = {
	    	callback:_dwrSuccess,
	        exceptionHandler:_dwrFailure,
	        scope: this
	    };

	    // Get ready to send the request URL
	    var dwrServiceMethod = this.liveData;
	    dwrServiceMethod.call(this, oRequest, _dwrCallMetaData)

	    return tId;
	}
});
YAHOO.lang.augmentObject(javachap.util.DWRDataSource, DS);

And configure YUI AutoComplete to use the DWRDatasource. Here Userservice.getUsers is the javascript function that you want to invoke to fetch the data from the server.

// Use an DWRDataSource
var oDS = new javachap.util.DWRDataSource(UserService.getUsers);

// Instantiate the AutoComplete
var oAC = new YAHOO.widget.AutoComplete(
    'userName', 'userNameContainer', oDS);
// we dont need '?query=sQuery', just return the sQuery instead.
oAC.generateRequest = function(sQuery) {
    return  sQuery;
};
Tagged as: , , 1 Comment