Xajax 0.2: Tips and Tricks: Overriding the xajax javascript






Xajax 0.2: Tips and Tricks: Overriding the xajax javascript

One of the coolest features about xajax is being able to change anything you don't like, so that it works the way you want; without modifying the core source code.

For an example of overriding, we'll show you how to make a simple animation appear any time there's an xajax call going on.

This example is deprecated in favour of the xajax.loadingFunction() and xajax.doneLoadingFunction() overrides. See the Creating a Loading Message tutorial.


[edit] Loading functions

For a start, we'll put an image on the page of some kind of animated gif that we'll show when we're doing an xajax command.

<img id="spinner" src="images/spinner.gif" />

And for now we'll hide it, so that it only shows when something's happening.

<img id="spinner" src="images/spinner.gif" style="display: none;" />

Now for the fun overriding part. We'll override the standard xajax.call() function to show our little spinner and then carry on as usual.

<script type="text/javascript">
    //keep around the old call function
    xajax.realCall = xajax.call;
    //override the call function to bend to our wicked ways
    xajax.call = function(sFunction, aArgs, sRequestType)
    {
        //show the spinner
        this.$('spinner').style.display = 'inline';
        //call the old call function
        return this.realCall(sFunction, aArgs, sRequestType);
    }
</script>

So now we've overridden the xajax.call() function so that it shows our spinner when we make an xajax call, we just have to override the xajax.processResponse() function to hide the spinner.

<script type="text/javascript">
    //save the old processResponse function for later
    xajax.realProcessResponse = xajax.processResponse;
    //override the processResponse function
    xajax.processResponse = function(xml)
    {
        //hide the spinner
        this.$('spinner').style.display = 'none';
        //call the real processResponse function
        return this.realProcessResponse(xml);
    }
</script>

Or if you're so inclined, you can hide the spinner after calling the processResponse function.


[edit] Function name passthru

In the forums, jumbooze asked if it was possible to pass along the name of the function to the xajax.processResponse() function so that he could do different things with the response depending on what function was called. The following overrides the getRequestObject, call and processResponse functions, just so the function name can be passed through.

<script type="text/javascript"><!--
            xajax.oldGetRequestObject = xajax.getRequestObject;
            xajax.getRequestObject = function()
            {
                this.lastRequestObject= this.oldGetRequestObject();
                return this.lastRequestObject;
            }
            xajax.realCall = xajax.call;
            xajax.call = function(sF, aA, sR)
            {
                var returnVal;
                var r;
                returnVal = this.realCall(sF,aA,sR);
                r = this.lastRequestObject;
                r.onreadystatechange = function()
                {
                    if (r.readyState <= 3 || r.status!=200)
                        return;
                    if (r.responseXML)
                        xajax.processResponse(r.responseXML, sF);
                    delete r;
                    r = null;
                }
                return returnVal;
            }
            xajax.realProcess = xajax.processResponse;
            xajax.processResponse = function(xml, functionName)
            {
                alert(functionName);
                return this.realProcess(xml);
            }
// --></script>


[edit] Referencing elements in another way

Another example of overriding is making it possible to refer to elements in an HTML page in a way other than by using the id. If we override the xajax.$() function we can get elements in other ways.

<script type="text/javascript"><!--
xajax.$ = function(path) {
    finalElement = new Object();
    pathBits = path.split("/");
    parentElement = document.getElementsByTagName('html')[0];
    try {
        for(i=0;i<pathBits.length;i++)
        {
            parentElement = parentElement[0].getElementsByTagName(pathBits[i]);
        }
        finalElement = parentElement[0];
    } catch (e) {}
    return finalElement;
}
// --></script>

so now you could call xajaxResponse functions like:

$objResponse->addAssign('body/div/span/h1','innerHTML','poor example');