8/17/2006
Using HTML Fieldset
Fieldset is useful in making semantically related fields appear together visually. Grouping fields this way makes it easier for user to understand the semantic relationship of the fields and they are pretty stylish too, which makes it a very useful element.
Legend allows us to give a proper caption to the fieldset and makes it even easier for the user.
Let’s take a quick look at a simple example. Suppose that we are gathering personal and professional information of a user. One way of achieving this is to use markup elements (like, h1, h2, h3…) for these two sections. But using fieldset makes it very simple just by adding two fieldsets, like
<fieldset>
<!—for personal information -->
</fieldset>
<fieldset>
<!—for professional information -->
</fieldset>
This way, it adds semantic relationship among the fields declared inside a fieldset. To give the legend, just use
7/06/2006
System error: -1072896658 in IE
Recently my team reported a problem while integrating one of the Ajax features I developed. Whenever they try to access that feature, it throws up an error "System error: -1072896658". I was suprised because that is working fine when I access in my test environment. Later after debugging in the integration environment, I found out that the problem is with charset. While configuring the server environment, they mistakenly specified the charset as "UTF8" (instead of utf-8) and that is the culprit of this error. So, whenever the response is received in the browser and accessed using xhr.responseText, MSXMl.dll (MSXML component) is not able to interpret the response and throwing a system error.
Solution:
By changing the charset to "utf-8", it started working absolutely fine.
Conclusion:
Make sure to specify the correct charset.
7/05/2006
Closing Tab/Window in Mozilla using window.close
Mozilla browsers will not allow you to close the window using window.close() unless the script opened the window. This is a little annoying sometimes. But there is a workaround to resolve this issue. If you observe the error message that is thrown by Mozilla Firefox, "Scripts may not close windows that were not opened by the script", it clearly says that if the script didn't open the window, you can't close that. But we open a blank page in the same window using "_self" as the target window and close the same window. In that way, the script opens the window (which is a blank one) and closes the window too.
So, to put this in the code,
< script >
function closeMe()
{
var win = window.open("","_self"); /* url = "" or "about:blank"; target="_self" */
win.close();
}
< /script >
< input type="button" name="CloseMe" value="Close Me" onclick="closeMe()" />
In mozilla, if there are more than one tabs open, then only the tab where this script is being executed, will be closed, not the whole window. But if there is only one tab open where this script is executing then the window will be closed.
Tested this script in Mozilla Firefox 1.5.0.4 and IE 6, XP SP2, Mozilla 1.7.12. I didn't test in any other browser.
5/30/2006
Using Dynamic Script Tags
One of the known problems in using XMLHttpRequest is that one can't make a request to a different domain than where the web page is coming from. It's a big limitation for some of the applications. There are some knows workarounds. For example, in IE we can change the security level by allowing access to data resources across domains. But we can't rely on this approach because not all other browsers support this configuration change.
There are other ways like using document.domain to set to a common domain, but this forces the response mechanism to HTML and in both the pages, we have to set the document.domain to same domain and this will not work if the domains are completely different. And many times, we may not have control over what's the response of the second domain request. One thing worth noting here is that subdomains are treated as separate domains.
If the response is script-centric then the best approach that can be used is "Dynamic Script Tagging". This appraoch doesn't use XHR. In this approach we construct script tags dynamically with the source (src attribute) pointing to the URL that has a response type as a script (script-centric response). Because the response is included in script tags, the response is evaluated by Javascript engine and that will be ready for use. I read some artciles describing this appraoch as JSON with Dynamic Script Tag. But I strongly oppose that. JSON is a pure data format. and if you just include pure JSON data as the response the data may be parsed correctly but has no real value. We need to capture that JSON data in some variable form or as a parameter to a function call. So, I call this method as Dynamic Script Tags with Script-centric approach ( It is not necessary to have JSON string included in the response, response can be a plain text assigned to a Javascript variable, like var test="this is a test" can be a valid response for this approach).
Let's see how we can use this method with an example. The example tries to get image search results from yahoo webservice API using two extra parameters output and callback.
output=json instructs yahoo webservice to send the response as JSON and callback will include method name in the response so that when Javscript evaluates the response, it knows that it has to call the method included in callback parameter. Example response for the yahoo webservice URL pointed by anchor:
Yahoo Image Search is
handleResults({"ResultSet":{
"totalResultsAvailable":"3",
"totalResultsReturned":2,
"firstResultPosition":1,"Result":[{"Title":"pKeely.jpg","Summary":"", "Url":"http:\/\/www.thepeoplephotographer.com\/hs01\/imgs\/pKeely.jpg",
"ClickUrl":"http:\/\/www.thepeoplephotographer.com\/hs01\/imgs\/pKeely.jpg",
"RefererUrl":"http:\/\/www.thepeoplephotographer.com\/hs01\/ahsagalleryjane.htm",
"FileSize":"19626",
"FileFormat":"jpeg",
"Height":"360",
"Width":"554",
"Thumbnail":{
"Url":"http:\/\/mud.mm-a6.yimg.com\/image\/2220417984",
"Height":"94",
"Width":"145"}
},{
"Title":"pkeely.jpg",
"Summary":"",
"Url":"http:\/\/www.qvcuk.com\/ukgif\/pkeely.jpg",
"ClickUrl":"http:\/\/www.qvcuk.com\/ukgif\/pkeely.jpg",
"RefererUrl":"http:\/\/www.qvcuk.com\/ukhtml\/elemis_expert.html",
"FileSize":"3722",
"FileFormat":"jpeg",
"Height":"100",
"Width":"100",
"Thumbnail":{
"Url":"http:\/\/mud.mm-a3.yimg.com\/image\/737339806",
"Height":"100",
"Width":"100"}}]}})
Working example link: http://www.geocities.com/keelypavan/dynamic_script_tag_ex.html
It constructs the script tag dynamically using document.createElement, sets the src attribute of the script tag and inserts that in head tag of the HTML page, simple....The code looks like this:
var headTag = document.getElementsByTagName("head").item(0);
var scriptTag = document.createElement("script");
scriptTag.src = url;
headTag.appendChild( scriptTag );
One problem I came across recently worth mentioning is, if the server request is using custom redirect then this method will not work. When I say custom redirect, I mean the responses using refresh attributes with META tags like:
<META HTTP-EQUIV="Refresh" CONTENT="0; URL=someURL">. In this case, Javascript can not evaluate META tags and it fails producing a Javascript error.
4/24/2006
Data Interchange formats for Ajax based applications
With the introduction of Ajax, the classic web-applications are moving towards sending data instead of content to the web browser (in most of the cases). The emphasis on data interchange formats is more than before. This article points out available data interchange formats.
If you consider a normal web-application (non-Ajax), server sends some content (normally, HTML content) and like a faithful servant, web browser displays it and it may have Javascript working but to a limited level. But when we talk about richness of the application, we need something more than this. Most part of how we display the content should be left to the application running in browser, so that it can change the content or even look and feel dynamically, i.e. Ajax app, especially Javascript.
As we all know, the XMLHttpRequest is the core component of Ajax and it communicates with the server to get data to display in the browser without any reload of the page. Different applications use different data formats based on their application needs.
Following types of data interchange I can think of in the industry now.
- XML (eXtensible Markup Language)
- JSON (Javascript Object Notation)
- String with delimiters
- Script-centric approach
- Classic way of sending content.
Well, first three formats together can be considered data-centric approaches. But for clarity I am separating them. Let’s discuss each of the formats individually.
XML:
XML is a web standard for data interchange formats. It’s been around for quite sometime now. The support for XML in Javascript is very good as most of the browser implemented XML DOM specifications. The main usage of XML is that structured and hierarchical data can be represented very well and it’s readable by human beings. This comes with a cost of including meta-data, which describes what that data represents. Of course, I have seen many XML documents, which you can’t make out anything from but let’s keep that aside for now. One good thing about this is its pure data representation, which lacks in HTML. (HTML represents data intermingled with styles and formatting.)
Once you get the XML content as a response to the client-side you can use XSLT to transform the data into HTML content or you can use XML DOM API to parse and access XML and form HTML content, may be using innerHTML or standard DOM API.
Let’s take an example and see how we can represent the same data/content in all the formats. The example I am going to take is folder contents’ information. The XML is self-explanatory, so I am not spending much time explaining what it represents.
<?xml version="1.0"?>
<items>
<item>
<name>Test Document</name>
<type>document</type>
<creator>Test creator</creator>
</item>
<item>
<name>Test Folder</name>
<type>folder</type>
<creator>Test Creator 2</creator>
</item>
<item>
<name>Test Shortcut</name>
<type>shortcut</type>
<creator>Test Creator 3</creator>
</item>
</items>
JSON:
JSON is a light-weight data interchange format. It’s a text (string) representation of Javascript objects. An object in Javascript is represented in key, value pairs. A key is a string enclosed in double-quotes whereas the value can be number, string, boolean (true or false), object, array or null. Following paragraph explains JSON format in brief.
The advantage of JSON is that it’s more compact than XML format and parsing JSON is a lot simpler than XML. You just need to pass JSON string to eval of Javascript or you can also download JSON parsers for different programming languages from http://www.json.org/. As we have parsers for most of the famous programming languages, it makes JSON a good data interchange format. I know that a lot of people think that eval is very evil but doing eval once to evaluate the JSON string will not cause any big performance impact. But if the data grows larger then definitely JSON will not be a good option.
Example: Let’s take the same example I represented in XML and write that in JSON format.
{items:[
{"name": "Test Document", "type": "document", "creator": "Test creator"},
{"name": "Test Folder", "type": "folder", "creator": "Test Creator 2"},
{"name": "Test Shortcut", "type": "shortcut", "creator": "Test Creator 3"}
]}
String with delimiters:
Though it’s not a standard to use a plain string with delimiters as the response format, it has some advantages. We can use regular expressions or split the string into pieces using the delimiter and use the data as an array. Not much of processing is required for parsing the string.
The problem with this approach is that we need to rely on the position of the elements. And if there is any change in the positions of the elements (data) then it requires a change in the client side code. And representing deep hierarchical data is very difficult and error-prone in this approach.
Example:
The data represented in two examples above could be represented in this approach as:
Test Document#document#Test creator$$Test Folder#folder#Test Creator 2$$Test Shortcut#shortcut#Test Creator 3
As you see this format is very compact because it doesn’t contain any meta-data but as the nested ness of data increases, like corporate taxonomy, representing that data is this fashion would definitely be a problem.
Script-centric approach:
In this approach a piece of script will sent from the server like assigning values to variables, function calls, which will be dynamically evaluated at the client side to perform the necessary actions.
The disadvantage of this approach is that it assumes some Javascript environment (like some functions defined in the page) at the client side. This means more coupling with the response with the page that’s requesting the resource.
Example: As we can’t represent data as-is and there will be piece of Javascript code as a response in this approach, there could be multiple ways you can represent this.
Response:
var matchingItems = {items:[
{"name": "Test Document", "type": "document", "creator": "Test creator"},
{"name": "Test Folder", "type": "folder", "creator": "Test Creator 2"},
{"name": "Test Shortcut", "type": "shortcut", "creator": "Test Creator 3"}
]} //new lines are just for clarity.
someMethod( matchingitems,… )
Content-Centric Approaches:
In the content-centric approach, the response from the server contains HTML content. So, the client side application (Javascript) has to take the content as is and place the content in any container using innerHTML or related methods. The advantage of this approach is that there is no explicit parsing of the data required. I used “explicit”, because internally when you use HTML content, the data has to parsed and shown in the web page. But the disadvantage is that it’s data with formatting tags. If you want to reuse the data of a response in this approach then we have to rely on DOM methods to retrieve the data, which is cumbersome.
Example:
As the response would be in HTML format, we can represent this in many ways depending on the need. Here is a way:
Response:
<div><span>Test Document</span><span>document</span><span>Test Creator</span></div>
<div><span>Test Folder</span><span>folder</span><span>Test Creator2</span></div>
<div><span>Test Shortcut</span><span>shortcut</span><span>Test Creator3</span></div>
We can take this content as-is and insert as HTML content in any of the allowed elements using innerHTML (or related) method. There’s not much processing required at the client side.
Sites/Apps using these formats:
XML:
Script-centric approach:
JSON format:
Conclusion: Depending on application needs, appropriate data interchange format has to be chosen. This article just describes the options available and the decision is yours.
I’ll update this article whenever I get some more time.
4/10/2006
Faster way of accessing DOM elements with same ID
This technique uses, document.all for getting the elements with the same ID. I know it's not a standard to use document.all and same ID for multiple elements. But this article shows you that there is a way and I am not encouraging you to use same ID for multiple elements. Now, most of the browsers implemented document.all, making it easier to use and no there's no cross-browser play you have to do in your code.
document.all represents all elements in the page and we can use this collection to get an element/elements with some specific ID. So, to get an element with "test" ID, we can use document.all['test'] to get that element. At the same way, if there are more than one element with that ID, a collection of nodes will be returned. But Alex went ahead and developed his own code for doing this, which is way slower than using document.all.
For demonstration purposes, I developed one example which writes 1000 divs to document onload of the page and page contains, two buttons, one gets elements using Alex's method and the second button uses document.all to get the nodes. Please check the fastness by yourself with the following link.
Link to example: http://www.geocities.com/keelypavan/DOMFasterMethods.html
3/30/2006
Reusing XMLHttpRequest Object in IE
In the current project I am doing, I implemented AJAX technique and using one instance (yes, you heard it right, only one instance) of XMLHttpRequest object without abort calls and I use IE 6, XP SP2. There is one little trick that you have to use to reuse one instance. I'll take the same example developed by the author in the blog Reusing XMLHtpRequest - dilema and show you how to reuse XMLHttpRequest object.
The code developed in the article uses the javascript statements
req_fail_IE.onreadystatechange = processReqChange_fail_IE;
req_fail_IE.open("GET", url, true);
req_fail_IE.send("");
where it assigns the callback handler to the XMLHttpRequest, open the request and send the request which actually transmits the request.
Instead of this piece of code, just try using the following code and it will do the trick. Believe me and it's worth trying.
req_fail_IE.open("GET", url, true);
req_fail_IE.onreadystatechange = processReqChange_fail_IE; //changed the position of callback handler
req_fail_IE.send("");
I worked on two examples. One that is originally created by Eric,
http://www.geocities.com/keelypavan/Non_Working.html .
and the code I changed (just changed whatever I mentioned above and nothing else, that's why you still see button names as "bad-test1" and "bad-test2", but don't care, both buttons still work even if they are named "bad"). http://www.geocities.com/keelypavan/working.html .
Note: Please bear with those Yahoo geocities ads and if you have pop-up blocker, you may get Javascript errors and these errors are from geocities ads code, please ignore them.
One more important point that I observed is, the request is getting fired even in the first example for the second button, which is not showing up any alert, but the callback handler is not getting called. So, it has to do with assigning callback handler to the XMLHttpRequest's onreadystatechange.
If it doesn't work, please let me know, because I only tested in IE 6, Mozilla Firefox 1.0.7 and no other versions.
Have a great reuse of XMLHttpRequest object and stop memory leaks ( update: I haven't demonstarted this piece).
For demonstration purposes, I created one example which creates a XHR object when loading and issues 5 requests immediately one after the other in a loop upon a click of "Get Data" button. If you have any TCP probe tools like HTTPWatch or anything like that, please see the requests being fired from the browser. Except for the last call, all previous 4 calls will be "abort"ed. ( There is a basic free version of HTTPwatch available if you don't have one.).
link to the example: http://www.geocities.com/keelypavan/Request_abort_test.html
Probably, this is one of the best practices to call open before setting onreadystatechange and may be calling abort if the request is in process.
2/21/2006
Google Suggest and AJAX
Note: If you don’t know what google suggest is all about, I recommend you visit http://www.google.com/webhp?complete=1&hl=en before reading this article. I am not getting into code level as the Google code is copyrighted.
The answer to this is AJAX. Yes, Google suggest is using AJAX for getting suggestions from the server and displaying it. This kind of auto-filling feature is becoming a standard these days with the help of AJAX. Let’s see now what’s happening when we type in search text box of Google suggest. This is a very good example for responsiveness and rich client side application with AJAX.
For this discussion I am not considering the backend.
1. When page loads up, Google sets up the environment, like creating XMLHTTPRequest object, creating an empty div in the page for displaying suggestions. Here the X and Y coordinates and width of the search box are calculated and using these, div’s top, left, width style coordinates are set so that suggestions layer displays appropriately in alignment with search box. Here is the code to calculate X and Y coordinates. This is not Google code, I found this in: http://www.quirksmode.org/js/findpos.html
function findPosX(obj)
{
var curleft = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curleft += obj.offsetLeft
obj = obj.offsetParent;
}
}
else if (obj.x)
curleft += obj.x;
return curleft;
}
function findPosY(obj)
{
var curtop = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curtop += obj.offsetTop
obj = obj.offsetParent;
}
}
else if (obj.y)
curtop += obj.y;
return curtop;
}
2. When user types in the search text of Google suggest’s search box, an asynchronous request will be sent to the server. The url for this is http://www.google.com/complete/search?hl=en&js=true&qu=pavan where qu denotes the suggest query term.
3. As you type, the query term differs and Google suggest gets the new information for auto-filling. I did a test on how fast it’s sending and getting the request for the fast typist. Look at the following URLs that are fired when I continuously type the search term. The whole search term I typed is “how google suggest is working”.
200 | http://www.google.com/complete/search?hl=en&js=true&qu=H |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=How%20 |
Aborted | http://www.google.com/complete/search?hl=en&js=true&qu=How%20goo |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=How%20googl |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20s |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20sug |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20sugges |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20suggest%20 |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20suggest%20is |
Aborted | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20suggest%20is%20w |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20suggest%20is%20work |
200 | http://www.google.com/complete/search?hl=en&js=true&qu=how%20google%20suggest%20is%20working |
4. If you observe, it’s aborting certain requests based on how fast you type.
5. The result of these HTTP requests are a simple string. For example for the first URL in the list, the response from the server is:
sendRPCDone(frameElement, "H", new Array("hotmail", "hotmail.com", "home depot", "http", "hp", "holiday inn", "honda", "horoscopes", "harry potter", "hsbc"), new Array("46,000,000 results", "1 result", "7,270,000 results", "1,370,000,000 results", "165,000,000 results", "14,600,000 results", "36,600,000 results", "8,020,000 results", "12,500,000 results", "3,430,000 results"), new Array(""));
6. If you observe, it’s nothing but a call to Javascript function (i.e., sendRPCDone ), reference to the DIV/IFrame element and suggestions in an array format but in a string format and this string can be “eval”ed in Javascript to call the function.
7. It then takes these arrays and construct a series of DIVs, SPANs and includes these DIVs and SPANs in the main suggestions DIV that was created at the page load. That’s when you see the suggestions coming up.
Just to add: Google has implemented Google suggest in the latest beta version tool bar. This also hits the server using HTTP and the URL is a little different. URL for getting suggestions for toolbar is: http://toolbarqueries.google.com/complete/search?q=google&output=toolbar&hl=en and the response is also different from the above. For this toolbar version, the response is in XML. The following is the sample XML for this.
<toplevel>
<completesuggestion><suggestion data="google.com"><num_queries int="1"></completesuggestion>
<completesuggestion><suggestion data="google toolbar"><num_queries int="3170000"></completesuggestion>
<completesuggestion><suggestion data="google maps"><num_queries int="6890000"></completesuggestion>
<completesuggestion><suggestion data="google scholar"><num_queries int="2210000"></completesuggestion>
<completesuggestion><suggestion data="google mail"><num_queries int="20600000"></completesuggestion>
<completesuggestion><suggestion data="google images"><num_queries int="21500000"></completesuggestion>
<completesuggestion><suggestion data="google tool bar"><num_queries int="3460000"></completesuggestion>
<completesuggestion><suggestion data="google map"><num_queries int="10500000"></completesuggestion>
<completesuggestion><suggestion data="google uk"><num_queries int="16300000"></completesuggestion>
<completesuggestion><suggestion data="google email"><num_queries int="20900000"></completesuggestion>
</toplevel>
1/18/2006
Using AJAX
AJAX is a buzzword these days. What really is AJAX ? Is it a new technology ? New framework ?
AJAX ( Asynchronous Javascript And XML ) is mainly used for manipulating the part of the web page and transfering some computation to the client system. Using this technology the page need not be reloaded when a part of the page changes because of user actions. This can be achieved by dynamically getting the data from the server when user interaction happens using the XMLHTTPRequest object. This is the new approach of developing rich client application.
AJAX is the mix of :
The traditional problem we have is, a lack of interactiveness for web applications like Desktop applications. When we submit a form or request some data from the server from the client side, the client has to wait till the request is processed and response is sent back to the client. If the server side request handler is taking long time to process the request, the client has to wait till the response comes back, probably with "working-in-background" mouse pointer or "Busy" mouse pointer. This is really annoying to the users and if user clicks many times on the windows that’s working on the request, OS may report that window as "Not Responding" and shows a blank white screen with just the title bar appearing (referring to IE on Windows). And users like me will definitely go to the taskbar and try to end the process. What if we can do this request processing work in the background asynchronously not disturbing the front-end screen and display a proper and relevant message "Processing Request" or "Waiting for reply" and allow the user to continue with some other tasks in the same window.
A Simple usecase:
In the web application I am working on has user selection field, which can be used to select any corporate user. (This is used to select users in a HTML form). Once the user selects "user selection" field and selects the particular corporate user, then the information regarding the selected user , like phone number, mailstop, mail address, manager, will be displayed in other fields of the form. The present solution developed waits till the request is processed and user can’t do any other task, like filling up other fields of the form in the same page. And sometimes, it takes nearly 30 seconds to 1 min for the response. If the user tries to click the window two or three times during this period then a blank window will appear and nothing works. And as I told you before, users like me will definitely kill the window using Task Manger and I have done that many times. This is a real annoying situation for the end user. This can be quite enough for a user to stop using the application altogether. So, what if we process that request of getting user information in the background asynchronously and still allowing the user to work on other fields of the form and process the information once we get the response from the back-end server ?
This kind of situations can be very well handled using AJAX, which has A ( Asynchronous ) at it’s core. Let’s get to the code and see how we can use AJAX in an application.
XMLHttpRequest Object:
One of the core component in AJAX framework is XMLHttpRequest object which allows asynchronous processing. XMLHttpRequest object also supports events. So, we can take actions whenever that’s necessary instead of continously checking for the status of the request. For example, we can just set a event handler to execute when the request is completed and response is received and continue with other tasks in the page and or wait for user input. This object also supports XML content. If the response is XML content then we can directly get a XML DOM object instead of taking the string and constructing the XML DOM object explicitly. Let’s look at the features of this object.
Object Methods (Most commonly used ):
open( method, URL, [isAsynchronous]) : This method is used to tell XMLHTTPRequest object which url to be considered to open the connection, what’s the method to use (GET/POST/PUT) and whether to process this request (accessing the specified URL) asynchronously or synchronously. The third parameter is option and by default it’s true, meaning that the request is processed asynchronously. The other optional parameters include username and password.
Example:
var xmlHttpRequest; //XMLHTTPRequest object
...... ( object construction goes here...will look into this later)
xmlHttpReuqest.open("GET","http://www.geocities.com/keelypavan/test.xml",true) // This method tells the object to get http://www.geocities.com/keelypavan/test.xml using GET method asynchronously. This is a dummy URL I used for demonstration purpose.
Note: This open doesn’t really open the connection to the server. We should call send(..) method for the request to be actually sent.
send( parameters as string ) : This method is used to actually send the request to the server for processing. Parameters if any specified will be sent to the server. Typically if the method id GET then the parameter will be null or an empty string or call the method without any parameters. If the method is POST then the parameter string would be the POST parameters in query string format, i.e. name=value pairs delimited by "&".
Example:
var xmlHttpRequest; //XMLHTTPRequest object
xmlHttpRequest.send( null ); //for GET
xmlHttpRequest.send( "name1=value1&name2=value2....");
Note: Make sure to set the onreadystatechange event handler before using the send method on the object.
abort():This Method aborts the request operation.
setRequestHeader( headerName, headerValue): Sets the request headers that will be sent to the server with the request.
Example:
var xmlHttpRequest; //XMLHTTPRequest object
xmlHttpRequest.setRequestHeader("IF-MODIFIED-SINCE","Sat, 04 Feb 2006 17:47:00 PST");
getResponseHeader( headerName ): Gets the specified response header sent by the server. Example response header are, content-type, content-length etc.
getAllResponseHeaders():Gets all the response header with header name and value as a string.
Properties:
readystate: Returns the ready state of the http request, which represents the internal state of the obejct. Values are listed below.
0 | Unintialized |
1 | Loading |
2 | Loaded |
3 | Interactive |
4 | Completed |
onreadystatechange: Sets the event handler function which will be called everytime there is a state change (readystate value change).This method is useful as we are requesting the resource from server asynchronously not waiting for the response. So, applications can use this method to come back and perform the necessary action when the request is completed.
status: Returns the status sent by the server. This status is HTTP status code. At the high level these codes mean:
1xx | Informational |
2xx | Successful |
3xx | Redirection |
4xx | Client Error |
5xx | Server Error |
statusText:Returns the text message (string) associated with the status code returned by the server.
For Example: Server send "OK" with the status code 200.
responseText: Returns the content of the response as a string returned by the server. Using this properly when the object is not is completed "readystate" will give an error.
reponseXML: Returns the XML DOM Document object if the response content is XML. For this to work, the server should send the XML content with content-type set as "text/xml" otherwise the responseXML will be empty. This is an important thing for developers as sometimes everything would be fine, the response will be XML content and XML will be well-formed but the responseXML method will not return DOM Document object.
If the response content is not well-formed XML, then the responseXML will return DOM Document with the parseError properly set so that applications can be aware of the problem.
Example:
Now let’s take an example and see how AJAX works.
Note: The sample application I developed works in IE, will try to develop a cross-browser app soon.
The sample application gets the RSS feeds from http://www.traffic.com/ site and displays them in the page.
The link to the application is: http://www.geocities.com/keelypavan/Ajax_traffic_update.html
Note: As this application tries to get the RSS feeds from traffic.com site, the security option allowing access to other domain resources should be enabled.
Object Creation:First let’s look at the object creation.
Object creation code:
if( window.XMLHttpRequest )
{
try{
xmlHTTPObj = new XMLHttpRequest();
}catch(e)
{
xmlHTTPObj = null;
}
}
else if( window.ActiveXObject )
{
try{
xmlHTTPObj = new ActiveXObject("MSXML2.XMLHTTP");
}catch( e )
{
xmlHTTPObj = null;
}
if( xmlHTTPObj == null )
{
try{
xmlHTTPObj = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e)
{
xmlHTTPObj = null;
}
}
}
This code uses the object detection technique to find out whether the object is defined in the browser environment. If yes, then this code creates that particular object and returns it. The other way of creating this object is using browser detection technique, meaning, check which browser is executing this piece of code and create the object accordingly. If it can't create the object, it would return a null value.
Sending Request:
Piece of code used for sending request:
document.getElementById("trafficDetails").innerHTML = "Loading Data ...";
var selectedCity = obj.options[ obj.selectedIndex ].value;
if( selectedCity != "" )
{
xmlhttp.open("GET",rssXMLBaseURL+trafficRSSXMLs.get( selectedCity ),true );
xmlhttp.setRequestHeader("If-Modified-Since","Thu, 26 Jan 2006 00:00:00 GMT");
xmlhttp.onreadystatechange = processRequest;
xmlhttp.send( "" );
}
else
{
document.getElementById("trafficDetails").innerHTML = "Select a city";
}
it uses, open(...), setRequestHeader(...), onreadystatechange, send() with the XMLHttpRequest object.
The first method used with XMLHttpRequest object is open(...). This method assigns the HTTP method to use to get the resource, URL and asynchronous flag.
setRequestHeader method is used in this case to check to see if the server resource has changed after the specified date and time. This has been set to a past date to get the content everytime.
onreadystatechange(..) method is used to set the event handler method.
At this point, the request is not yet sent but all other parameters are set. The next method send() transmits the HTTP request to the server. Be sure to set event handler method, onreadystatechange, before using send() method on the object.
Event Handler Method ( i.e. processRequest ): This method will be called every time there is a change in the readystate of the object. This method checks the readystate value and if it’s in completed state ( value 4 ) then it tries to see what’s the status code returned by the server. If status is 200 (successful) then it tries to get the content with responseXML and transforms using XSLT. You can get the XSLT source by clicking this link: http://www.geocities.com/keelypavan/trafficConditions.xsl. If the status code is not 200, then it reports an error string statusText.
The piece code is:
if( xmlhttp.readystate == 4 )
{
var divObj = document.getElementById("trafficDetails");
if( xmlhttp.status == 200 )
{
divObj.innerHTML = xmlhttp.responseXML.transformNode( xsltDoc );
}
else
{
divObj.innerHTML = "Could not load data";
alert( "Error:"+xmlhttp.statusText );
}
}
End of example:
Conclusion:
AJAX is very much useful to get the dynamic content from the server. This can be used to get the content of from the server even after the page load, in better terms, lazy loading and create very rich and interactive applications.