|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThis article presents a simplified AJAX library written in JavaScript, hopefully many developers will find it useful. AJAX is an exciting new technology and will change the way we develop our web applications. Basically the library comprises of two methods, no classes or anything fancy, (I said it was simple). These two methods were designed with ease of use in mind. One allows flexibility by being able to pass the response to a JavaScript function, which allows you to do anything JavaScript can do with the returned data/response. The other sets the BackgroundI had heard a lot about this new AJAX technology and seen some examples on the web which looked really cool, so I thought I'd do some R&D on the subject. The first thing I do when researching new technologies is look around the web for some libraries or code, and read, read, and read some code. As usual some are useful, a lot are overly complicated. So I take the useful and overly complicated code, and re-work it into something simple and easy to use. My background is PHP and Linux, but now I'm a Microsoft .NET developer. Because of this .NET developers may or may not notice that I use more traditional techniques than the new ASP.NET way. This example uses ASP.NET and JavaScript. The library itself can be used with multiple server side languages. Prepare to be amazed by the jaw-dropping simplicity of this code. Using the codeWell let's get down to it... The first thing to do is include the ajax.js JavaScript file in your web page like this: <script language="javascript" src="ajax.js"></script>
Now we can use the two JavaScript functions in the ajax.js file. The first function in the library, and the one that I use most, is <input type="button"
onclick="SetInnerHTMLFromAjaxResponse('?button=1','div_to_put_html')"
value="Get Some Html From The Server" ID="Button1" NAME="Button1" />
<div id="div_to_put_html"></div>
The first argument '?button=1' is the URL to send the request. Seasoned web developers will know that this is submitting the variable "button" with a value of "1" to the current page. You can of course submit the request to anywhere on the internet, but essentially to a server that will know what to do with the request and return some HTML. The function will place the returned HTML/response and place it in the You can call this function from anywhere in the JavaScript. function GetFilteredCustomerTable() {
var name = document.getElementById('cust_surname').value;
var country = document.getElementById('cust_country').value;
var min_orders = document.getElementById('min_orders').value;
SetInnerHTMLFromAjaxResponse('?action=get_customers_table&name='+name+
'&country='+country+'&min_orders='+min_orders,'div_to_put_html')
}
You can see that we are passing more parameters to the page in this example. These parameters can be used in the server side script to select/filter records from a database, create some HTML from the results and return it. Now onto the second JavaScript function: <input type="button"
onclick="PassAjaxResponseToFunction('?getsomecsvdata=1',
'FunctionToHandleTheResponse',
'\'div_0\',\'div_1\',\'div_2\'');"
value="Pass The Response To A Function" ID="Button2" NAME="Button2" />
function FunctionToHandleTheResponse(response, d0, d1, d2){
//we are expecting r to look like 'value1,value2,value3'
var data = response.split(',');
document.getElementById(d0).innerHTML = data[0];
document.getElementById(d1).innerHTML = data[1];
document.getElementById(d2).innerHTML = data[2];
}
Again the call to Passing the optional param argument is not necessary as the same result could be achieved by doing this: <input type="button"
onclick="PassAjaxResponseToFunction('?getsomecsvdata=1',
'FunctionToHandleTheResponse');"
value="Pass The Response To A Function" ID="Button3" NAME="Button3" />
function FunctionToHandleTheResponse(r){
//we are expecting r to look like 'value1,value2,value3'
var data = r.split(',');
for(var i=0;i<data.length;i++){
document.getElementById('div_'+i).innerHTML = data[i];
}
}
Although, passing ' And that's all there is to it. Hopefully you can see how easy this will be to use. The JavaScript Source CodeI'm not going to spend much time explaining the source. I will point out that setting There's not much to the ajax.js JavaScript file, so here is the code: /**
SAL - Simple Ajax Lib. 23-Sep-2005
by Nigel Liefrink
Email: leafrink@hotmail.com
*/
var debug = false;
/**
<summary>
Browser Compatability function.
Returns the correct XMLHttpRequest
depending on the current browser.
</summary>
*/
function GetXmlHttp() {
var xmlhttp = false;
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest()
}
else if (window.ActiveXObject)// code for IE
{
try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP")
} catch (e) {
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")
} catch (E) {
xmlhttp=false
}
}
}
return xmlhttp;
}
/**
<summary>
Gets the response stream from the passed url, and then calls
the callbackFuntion passing the response and the div_ids.
</summary>
<param name="url">The url to make the request
to get the response data.</param>
<param name="callbackFunction">The function to call after
the response has been recieved.
The response <b>must</b> always
be the first argument to the function.</param>
<param name="params"> (optional) Any other parameters
you want to pass to the functions.
(Note: only constants/strings/globals can be passed
as params, most variables will be out of scope.)
</param>
<example>
<code>
PassAjaxResponseToFunction('?getsomehtml=1',
'FunctionToHandleTheResponse',
"\'div1\',\'div2\',\'div3\'');
function FunctionToHandleTheResponse(response, d1, d2, d3){
var data = response.split(';');
document.getElementById(d1).innerHTML = data[0];
document.getElementById(d2).innerHTML = data[1];
document.getElementById(d3).innerHTML = data[2];
}
</code>
</example>
*/
function PassAjaxResponseToFunction(url, callbackFunction, params)
{
var xmlhttp = new GetXmlHttp();
//now we got the XmlHttpRequest object, send the request.
if (xmlhttp)
{
xmlhttp.onreadystatechange =
function ()
{
if (xmlhttp && xmlhttp.readyState==4)
{//we got something back..
if (xmlhttp.status==200)
{
var response = xmlhttp.responseText;
var functionToCall = callbackFunction +
'(response,'+params+')';
if(debug)
{
alert(response);
alert(functionToCall);
}
eval(functionToCall);
} else if(debug){
document.write(xmlhttp.responseText);
}
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
}
/**
<summary>
Sets the innerHTML property of obj_id with the response from the passed url.
</summary>
<param name="url">The url to make the request
to get the response data.</param>
<param name="obj_id">The object or the id of
the object to set the innerHTML for.</param>
*/
function SetInnerHTMLFromAjaxResponse(url, obj_id)
{
var xmlhttp = new GetXmlHttp();
//now we got the XmlHttpRequest object, send the request.
if (xmlhttp)
{
xmlhttp.onreadystatechange =
function ()
{
if (xmlhttp && xmlhttp.readyState==4)
{//we got something back..
if (xmlhttp.status==200)
{
if(debug)
{
alert(xmlhttp.responseText);
}
if(typeof obj_id == 'object')
{
obj_id.innerHTML = xmlhttp.responseText;
} else {
document.getElementById(obj_id).innerHTML =
xmlhttp.responseText;
}
} else if(debug){
document.Write(xmlhttp.responseText);
}
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
}
ASP.NET - Using the code, the server sideFor ASPX pages, I will create a method to check if the request is an AJAX request, then only return what is needed in the response. It is important to call ///Standard ASP.NET event
private void Page_Load(object sender, System.EventArgs e)
{
HandleAjaxEvent();
//do all the normal rendering for the page...
}
/// <summary>
/// Checks the query string to see if the request is an ajax event.
/// If it is, only return the specific data/html needed.
/// Then call Response.End() so as not to render
/// the rest of the page to the Ajax response.
/// </summary>
private void HandleAjaxEvent()
{
string bNum = Request.QueryString["button"];
//if something that indicates an ajax request, just return the data only.
if(bNum != null && bNum.Length > 0)
{
switch (bNum)
{
case "1":
//demonstrates the use of the GetHtml() function.
//if you wanted to use controls that
//are created using the designer on the aspx page,
//you can set their visibility to false initially.
//then temporarily set visibility to true,
//call GetHtml()
//This would be the best thing to do with
//a repeater, trying to create one in code is a lot of work.
//(or just use for loops to create html.)
Label l = new Label();
l.Text = "Ajax is hot!";
l.BackColor = Color.Honeydew;
l.BorderWidth = 6;
l.BorderStyle = BorderStyle.Groove;
l.BorderColor = Color.Goldenrod;
Response.Write(GetHtml(l));
Response.End();
break;
case "2": //Get Customer Data
//Just return some csv data
string name=Request.QueryString["name"];
Response.Write(GetCustomerDetailsByName(name));
Response.End();
break;
case "3": Return a Filtered DataGrid
//create a data grid using the
//min_orders filter and return the html.
DataGrid dg = new DataGrid();
dg.AutoGenerateColumns = true;
string min_orders=Request.QueryString["min_orders"];
DataTable dt = GetCustomersDataTable();
DataView dv = new DataView(dt);
dv.RowFilter="Orders > "+min_orders;
dg.DataSource = dv;
dg.DataBind();
Response.Write(GetHtml(dg));
Response.End();
break;
}
}
}
///<summary>Get customer csv string
/// from the data base by name.</summary>
public string GetCustomerDetailsByName(string name)
{
return "Nigel,Liefrink,27";
//go get some data in the database
//and return it as a csv.
}
///<summary>Get a table from the database.</summary>
public DataTable GetCustomersDataTable()
{
//Go to the Database and return a table.
return new DataTable();
}
/// <summary>
/// Helper to get a html string
/// representation of the passed Control.
/// </summary>
/// <param name="c">Control to return Html for</param>
/// <returns>Html of control</returns>
private string GetHtml(Control c)
{
StringBuilder sb = new StringBuilder();
HtmlTextWriter tw = new HtmlTextWriter(new StringWriter(sb));
try
{
c.RenderControl(tw);
}
finally
{
tw.Close();
}
return sb.ToString();
}
Take note of the use of the Getting the demo project workingTo get the demo project working, unzip the sal_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/run the demo project. Points of Interest
|
||||||||||||||||||||||