Salajax: simple Ajax library solving back button and bookmarks for Ajax web applications

Salajax is a simplified Ajax library that handles back buttons, bookmarks and is extremely simple to use. Yes, Ajax is great. It does have some minor issues though, like the back button not working and the inability to use bookmarks. This library provides a simple class that will handle all these issues and more, without you having to think about it too much.
The Simple Ajax Library Ajax class (Salajax) tries to:

  • Make the back button work with Ajax
  • Make bookmarks work with Ajax
  • Run JavaScript contained in the Ajax response
  • Keep the .NET Viewstate
  • Submit forms as an Ajax request
  • Specify OnStart and OnEnd JavaScript functions to call
  • Specify an OnError JavaScript function to call when the Ajax response is an error
  • Set the HTML to display when updating a div with an Ajax request
  • Set the HTML to display when there is an error making the Ajax request
  • Be extremely simple to use
Basically, I'm hoping that the Salajax class will make it very easy to do everything and anything you could possibly want to do using Ajax.


Background

This article presents a simplified Ajax library written in JavaScript. Hopefully many developers will find it useful. Ajax is an exciting new technology that will change the way we develop our web applications. That was the introduction to the fist article I wrote on Ajax, presenting a simplified Ajax library with only two methods. I called it SAL, for Simplified Ajax Library.

Yes, Ajax was the big buzzword. It was going to revolutionise the web and the way we developed applications. Then somebody noticed a few minor problems, i.e. the back button did not work properly; users would most likely end up at the previous site they were visiting or become confused. Also, developers found that they couldn't run the JavaScript that was returned in the Ajax responses, plus more problems.

That's why I decided to build the next simplified Ajax library or SAL version 2. Things I wanted to add at the beginning were: making it a self-contained class, making the back button work, accounting for Viewstate, and giving backwards compatibility with SAL v1. Things I added on the way were: OnEvents, having customisable HTML when updating or at an error, and getting bookmarks to work. Also, updating multiple sections seems to be run on different threads now.

Not all the code is mine. I found some code on the internet that fits well and have maybe edited it. One example of this is the hash listener class, for which I have left the original comments of the author. However, a lot of the code is written by me. I can't guarantee that this will work on all browsers, however. It really does use a lot of complex JavaScript to make the back buttons work, etc. I have tested it in FireFox 2.0.0.3 and IE 6.0.2900.2180; it works well with those.

Using the code

Well, initially you will have to include the JS file in the head of your page like this:
<script language="JavaScript" src="Salajax.js">script>
Here is the comment contained at the top of the Salajax.js class:

/*
The Salajax Class.
Ajax class that allows use of the back button and bookmarks.
Written by Nigel Liefrink.

Usage:
    //set up the Salajax settings. Do this in the  of the page
    var SAL = new Salajax();
    sal.Debug = 0;
    sal.EnableBackButton(true); //turns on the back buttons.
    sal.EnableBookmarks(true); 
        //saves state in the clients cookies so bookmarks will work
        //provided they havn't deleted their cookies.
    sal.OnStart = 'TestOnStart()'; //enables a script to run before 
        //the request is made. e.g. change pointer/icon/loading section of 
        //page.
    sal.OnEnd = 'TestOnEnd()'; 
        //enables a script to run after the request is returned. 
        //e.g. change pointer/icon/loading section of page.
    sal.PresendHtml = '';
        //When calling  setInnerHTMLFromAjaxResponse the div will 
        //be updated with this html, set to null to turn off this feature.
    sal.OnError = 'DefaultOnError()';
        //set a function to pass to if there is an error.
    sal.OnErrorHtml = 
        'Error!'; 
        //When calling  setInnerHTMLFromAjaxResponse and there is 
        //an error, this will be displayed. set to null to turn off 
        //this feature.
    sal.EvalScripts = true;  
        //if set to true, will evaluate any JavaScript in the responseText. 
        //NOTE: to use/override functions returned in your responseText you 
        //must declare the functions in your Ajax response like this:
        //         var FunctionToChange = function(var1,var2) 
        //not like this : function FunctionToChange(var1,var2)
        //         { 
        //             //do stuff
        //         }
        //            
    this.KeepDotNetViewState = true; 
    //if set to true will post the current viewstate when using .NET 
    //not recommended when using bookmarks as viewstate can be huge.
    //end setting the Salajax settings.
    
    
    Some examples of main usage in a web page: (onclick events etc...)
    
    sal.PassAjaxResponseToFunction('/myscript.*?getsomehtml=1', 
        'FunctionToHandleTheResponse');
    sal.PassAjaxResponseToFunction(document.forms[0], 
        'FunctionToHandleTheResponse');

    sal.SetInnerHTMLFromAjaxResponse('/myscript.*?getsomehtml=1', 
        'id_of_div'); //using get and string of id div.
    sal.SetInnerHTMLFromAjaxResponse(document.forms[0], 
        object);//using post and object to change the innerhtml of.
    sal.SetInnerHTMLFromAjaxResponse('form', 
        'id_of_div');//using post ('form' will submit forms[0]'), 
                     //object to change the innerhtml of.

    Read function definitions for more detail.
    Note that initial values are all false for backward compatability.
*/

If you want back buttons to work for some calls but not others, simply create another instance of the class.

var SAL = new Salajax();
sal.EnableBackButtons(true)
//in the web page

<input class="code-string" type="<span" "submit" value="OK" 
    onclick="sal.SetInnerHtmlFromAjaxResponse('form','div_1');" />

var sal2 = new Salajax();
//in the web page

<input class="code-string" type="<span" "submit" value="OK" 
    onclick="sal2.SetInnerHtmlFromAjaxResponse('?gethtml=1','div_2');" />
 
 

For backwards compatibility with SAL version 1, I have included these two functions at the top of the script. THey demonstrate how you can use many instances to handle Ajax requests differently.


/* Backward compatability. */
function PassAjaxResponseToFunction(urlOrForm, callbackFunction)
{
    var SAL = new Salajax();
    sal.PresendHtml = null;
    sal.OnError = '';
    sal.ErrorHtml == null;
    sal.PassAjaxResponseToFunction(urlOrForm, callbackFunction);
}

/* Backward compatability. */
function SetInnerHTMLFromAjaxResponse(urlOrForm, obj_id)
{
    var SAL = new Salajax();
    sal.PresendHtml = null;
    sal.OnError = '';
    sal.ErrorHtml == null;
    sal.SetInnerHTMLFromAjaxResponse(urlOrForm, obj_id);
}
 
There's not much more to it than that. Just create the instance, set the properties and then start using the 2 main functions of the Salajax class in JavaScript events. To get the demo project working, unzip the Salajax_demo.zip file to an appropriate location like wwwroot, but anywhere will do. Create a virtual directory in Information Services Manager/IIS under the "Default Web Site" with an alias of "sal_demo" and the directory path referencing the sal_demo folder you unzipped. Opening the project in Visual Studio, you should now be able to compile, debug and run the demo project.

Points of interest

Cookies can only hold 4 Kb of data. So if you are keeping a lot of data in your forms, such as the .NET Viewstate, keeping bookmarks and the back button working with Ajax may not be the ideal solution for you.
Threading for each of the JavaScript calls now seems to work differently -- multiple threads -- now that the calls are wrapped up in an instance class.
The complexity of the JavaScript used to make the back button work makes me think that this code will most likely not be compatible with some browsers. It would be good to get feedback on compatibility from people.

0 comments: