Overview | File | Class | Tree | Index | Help
| The Gravey Framework and RATS RIA
PREV NEXT | FRAMES NO FRAMES

## grvAJAX.js

#### Summary

Collection of AJAX support routines.
Version: 2.5
Requires:

- grvUtils.js
- grvValidate.js

Author: Bruce Wallace (PolyGlotInc.com)

Class Summary
grvXMLreq | Constructor for grvXMLreq "object" which encapsulates a REST-style request/reply transaction that returns XML or Text.

Method Summary
`static Object` | `grvGetXHR()` method to create new XMLHttpRequest object
`static Object` | `grvIELoadXmlDOM( xmlURL )` SYNCHRONOUS IE-specific retrieve XML DOM from given URL
`static Object` | `grvIs_FF_AJAX()`
`static Object` | `grvIs_IE_AJAX()`
`static Object` | `grvLoadXmlDOM( xmlURL )` SYNCHRONOUS non-IE-specific retrieve XML DOM from given URL
`static Object` | `grvLoadXslDOM( xmlURL )` SYNCHRONOUS retrieve XSL DOM from given URL
`static String` | `grvXformDOM( xslDOM, xmlDOM )` transform given XML DOM using given XSLT DOM
`static String` | `grvXformURL( xslURL, xmlDOM )` transform given XML DOM using an XSLT retrieved from given URL

    // This file uses JSDoc-friendly comments [ http://jsdoc.sourceforge.net/ ]

    /**
     * @file         grvAJAX.js
     * @fileoverview Collection of AJAX support routines.
     * @author       Bruce Wallace  (PolyGlotInc.com)
     * @requires     grvUtils.js
     * @requires     grvValidate.js
     * @version      2.5
     */

    //////////////////////////////////////////////////////////////////
    // GRAVEY LEXICAL CODING CONVENTIONS:
    // (*) All private variables or functions start with "_"
    // (*) All variables and functions start with a lowercase letter
    // (*) All Classes start with an uppercase letter
    // (*) All Class methods and instance variables start with lowercase
    // (*) All Class "static" methods and variables start with uppercase
    // (*) All constants start with "k"
    // (*) All global variables start with "g"
    // (*) All event handler functions start with "on"
    //
    // (*) All Gravey utility global variables start with "gGrv"
    // (*) All Gravey MVC     global variables start with "gMVC"
    // (*) All Gravey EDO     global variables start with "gEDO"
    // (*) All Gravey utility functions start with "grv"
    // (*) All Gravey MVC     functions start with "mvc"
    // (*) All Gravey MVC event handler functions start with "onMVC"
    // (*) All Gravey EDO event handler functions start with "onEDO"
    // (*) All Gravey MVC classes start with "MVC"
    // (*) All Gravey EDO classes start with "EDO"
    //////////////////////////////////////////////////////////////////

    grvTraceCmp("grvAJAX.js: Begin");

    Class(grvXMLreq,["url"]);
    /**
     * @class Constructor for grvXMLreq "object" which encapsulates a REST-style
     * request/reply transaction that returns XML or Text. This class makes
     * multiple simultaneous requests possible, however, a separate instance
     * of this class is required for each request. This constructor will
     * automatically cause this request to be immediately launched unless
     * launch is suppressed.<p>
     * If post data is defined then this request is made via a POST (otherwise
     * via a GET) HTTP request.<p>
     * Any instance of this class can be created in "test mode" that reads
     * XML directly from an XML file rather than making a POST/GET request for XML.
     * This class has helper methods that will transform the response XML via
     * an XSL document specified via filename or URL.
     * @author Bruce Wallace  (PolyGlotInc.com)
     * @version 2.5
     */
    function grvXMLreq()
    {
    	/**
    	 * @param {String} url the URL to request XML from (or XML file path in test mode)
    	 * @param {Function} userCallbackFunction the callback to handle the XML when it arrives
    	 * [note: The callback will have this grvXMLreq object passed to it via
    	 *  both "this", and, as a single function argument.]
    	 * @param {String} optPostData optional post data string (should be "undefined" if not a POST req.)
    	 * @param {boolean} optWaitFlag optional "wait for reply" flag (i.e. DONT do this async if true)
    	 * @param {boolean} optSuppressLaunchFlag optional "suppress launch" flag
    	 * @throws ErrMsg if missing required parameter(s)
    	 */
    	this.konstructor = function( url, userCallbackFunction, optPostData, optWaitFlag, optSuppressLaunchFlag )
    	{
    		var self = this; //needed for closure

    		// initialize instance data
    		this.name   = "grvXMLreq" + grvTimestamp(); //mostly unique name
    		this.local  = false; //starting assumption
    		this.url    = url;
    		this.post   = optPostData ? optPostData : null;
    		this.async  = optWaitFlag ? false : true;
    		this.usercb = userCallbackFunction || function(){ grvError("Unhandled Reply=["+this.getResponseText()+"]"); };
    		this.cb     = function(){ self.cbwrapper(); };
    		if (!optSuppressLaunchFlag) this.launch();
    	}

    	/** method to return "this" as a human-readable string @type String */
    	this.toString = function(){ return grvObjectToString(this); }

    	/** method to launch "this" request */
    	this.launch = function()
    	{
    		this.xhr = grvGetXHR();
    		this.xhr.onreadystatechange = this.cb;
    		this.xhr.open( this.post?"POST":"GET", this.url, this.async );
    		// if POST, we tell the server to expect form-type parameters
    		if (this.post) this.xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
    		this.xhr.send( this.post );
    	}

    	/** callback wrapper method to relieve user callback from gory details of
    	 * XMLHttpRequest state transition handling.
    	 */
    	this.cbwrapper = function()
    	{
    	  if (this.xhr.readyState == 4)
    	  {
    		switch( this.xhr.status )
    		{
    		  case 0:
    			// local files return 0 on Mozilla and work...
    			// but on IE it doesn't work, so retry as local file
    			if (grvIs_IE_AJAX())
    			{
    				this.xhr = grvIELoadXmlDOM( this.url );
    				this.local = true;
    			}
    		  case 200:
    			this.usercb( this );		//support both method and subroutine calls
    			break;
    		  default:
    			if (!_kGrvAjaxTestData)	//suppress error msg on "Save" if we are using dummy xml files instead of real server
    				grvError( "Bad XML retrieve status["+this.xhr.status+"]["+ this.xhr.statusText +"] for ["+this.name+"]");
    		}
    	  }
    	}

    	/** get XML returned in the reply to "this" xml request
    	 * @return XML DOM @type Object
    	 */
    	this.getResponseXML = function()
    	{
    		return this.local ? this.xhr : this.xhr.responseXML;
    	}

    	/** get text returned in the reply to "this" xml request
    	 * @type String
    	 */
    	this.getResponseText = function()
    	{
    		return this.local ? null : this.xhr.responseText;
    	}

    	/** return the output from transforming the response XML
    	 * with the XSL in the specified URL/filename
    	 * @type String
    	 * @throws ErrMsg on fatal error
    	 */
    	this.xform = function( xslURL ) {
    		return grvXformURL( xslURL, this.getResponseXML() );
    	}

    	/** return the output from transforming the response XML
    	 * with the XSL in the specified XSL DOM
    	 * @type String
    	 * @throws ErrMsg on fatal error
    	 */
    	this.xform2 = function( xslDOM ) {
    		return grvXformDOM( xslDOM, this.getResponseXML() );
    	}
    }

    //////////////////////////////////////////////////////////////
    // Process XML via browser-side XSL...
    //////////////////////////////////////////////////////////////

    function grvIs_FF_AJAX(){ return document.implementation && document.implementation.createDocument; }
    function grvIs_IE_AJAX(){ return grvIs_IE_Pre7() || !grvIs_FF_AJAX(); }

    /** method to create new XMLHttpRequest object
     * @return "XMLHttpRequest object" @type Object
     * @throws ErrMsg if XML Request Objects arent supported by Browser
     */
    function grvGetXHR()
    {
    	 try { return new ActiveXObject("Msxml2.XMLHTTP"   ); } catch (e){ }
    	 try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){ }
    	 try { return new XMLHttpRequest();                   } catch (e){ }
    	 grvLoudThrow("XML Request Objects are not supported by this Browser.");
    }

    /** SYNCHRONOUS retrieve XSL DOM from given URL
     * @param {String} url the URL to request XSL from
     * @return XSL DOM @type Object
     */
    function grvLoadXslDOM( xmlURL )
    {
    	//IE needs Msxml2.DOMDocument load to do XSL tranforms
    	if (grvIs_IE_AJAX()) return grvIELoadXmlDOM( xmlURL );
    	return grvLoadXmlDOM( xmlURL );
    }

    /** SYNCHRONOUS non-IE-specific retrieve XML DOM from given URL
     * @param {String} url the URL to request XML from
     * @return XML DOM @type Object
     */
    function grvLoadXmlDOM( xmlURL )
    {
        var xhr = grvGetXHR();
        xhr.open( "GET", xmlURL, false );
        xhr.send( null );
        switch( xhr.status )
        {
    	  default:
    		  grvLoudThrow( "Bad XML retrieve status["+xhr.status+"]["+ xhr.statusText +"] for ["+xmlURL+"]");
          case 0:
        	  // local files return 0 on Mozilla and work...
        	  // but on IE it doesn't work, so retry as local file
        	  if (grvIs_IE_AJAX()) return grvIELoadXmlDOM( xmlURL );
          case 200:
        }
    	return xhr.responseXML;
    }

    /** SYNCHRONOUS IE-specific retrieve XML DOM from given URL
     * @param {String} url the URL to request XML from
     * @return XML DOM @type Object
     */
    function grvIELoadXmlDOM( xmlURL )
    {
        var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
        	xmlDoc.async = false;
        	xmlDoc.load( xmlURL );
    	if (xmlDoc.parseError.errorCode != 0)
    		grvLoudThrow("Error loading["+xmlURL+"]: " + xmlDoc.parseError.reason);
    	return xmlDoc;
    }

    /** transform given XML DOM using given XSLT DOM
     * @return transformed XML @type String
     * @throws ErrMsg on fatal error
     */
    function grvXformDOM( xslDOM, xmlDOM )
    {
    	if (grvIs_IE_AJAX()) return xmlDOM.transformNode( xslDOM );

    	// code for Mozilla, Firefox, Opera, etc.
    	var    xsltProcessor = new XSLTProcessor();
    	       xsltProcessor.importStylesheet   ( xslDOM );
    	return xsltProcessor.transformToDocument( xmlDOM ).documentElement.textContent;
    }

    /** transform given XML DOM using an XSLT retrieved from given URL
     * @return transformed XML @type String
     * @throws ErrMsg on fatal error
     */
    function grvXformURL( xslURL, xmlDOM ){
      return grvXformDOM( grvLoadXslDOM(xslURL), xmlDOM );
    }

    grvTraceCmp("grvAJAX.js: End");

Overview | File | Class | Tree | Index | Help
| The Gravey Framework and RATS RIA
PREV NEXT | FRAMES NO FRAMES

Documentation generated by JSDoc on Thu Jan 6 12:46:18 2011