Last updated .
Ajax allows you to communicate with the web server in the background without causing a page reload and without blocking. There are two main arguments for using Ajax:
Using Ajax it is perfectly possible to convert a web application consisting of several or many web pages into just a single page. That, in my view, is going slightly overboard. But Ajax can certainly improve an application when used in the right places. You don't need jQuery to use Ajax, but jQuery is supposed to make things easier.
Since Ajax is all about communicating with a server, we need a web server to test and document, but it is actually possible to simulate having a server by simply requesting the contents of a file. So, just to get started, here is a simple example of using jQuery to make an Ajax call to add some content to the UI:
This is what the file contains:
<span style="color:green;font-size:24px">Hello from server!</span>
And this is the page requesting that file, using the jQuery load method, when the button is clicked:
<script src="jquery-2.1.4.js"></script>
<button id="button">Load content</button><br></br>
<label>Response:</label>
<div id="content"></div>
<label>Ajax call status:</label>
<div id="status"></div>
<script>
// CLICK handler on button
jQuery("#button").click(function (event)
{
// Make Ajax call
jQuery("#content").load("ajaxtest.txt",
function (response, statusText, jqXHR)
{
jQuery("#status").text(statusText + ': '
+ response + "\r\n");
}
);
});
</script>
A click on the button yields this fabulous result:
jQuery updates the contents of the #content element with the response and the same response is also written to the #status element as text.
The load method performs an Ajax request, and replaces the contents of the elements in the set with the response.
The method has the format jQuerySet.load(url [, data] [, onCompleted])
, returning a reference to the jQuery set it is called on.
Name | Type(s) | Description |
url | String | url address. Optionally containing a jQuery selector expression. |
data | String/object/object[] | The data to send in the request. May be a preformatted string with url parameters. It can also be an object whose properties will get serialized or an array of objects having name and value properties. The request is a POST, unless a string (or nothing) is passed in this parameter, in which case a GET request is sent. |
onCompleted | function(response, statusText, jqXHR) | A callback function to be called after the response has been returned and loaded into the DOM. The function is called once for each element in the set, with the function context set to that element. The statusText is set to one of the values abort, error, notmodified (server responds with 304 - not modified) , parsererror (server responds with invalid data), success, and timeout. The jqXHR object encapsulates and extends the native XMLHttpRequest of the browser. |
If the load method is called on an empty jQuery set the Ajax request isn't made.
Using a static file instead of a real server is less than optimal, so I set up a server application to process the Ajax requests from the page. All it does is wrap the parameters it receives in an Html table construct. In other words, it returns an Html fragment ready to be inserted on the page. In case you have Visual Studio, here is what I did to create a server application to test the Ajax requests:
I modified the example to call the server at an entry point named "handler1", this time sending an object. I designed the server method to respond by echoing the request data, packed in an Html table:
<button id="button">Load content</button><br></br>
<label>Response:</label>
<div id="content" style="margin:10px;"></div>
<label>Ajax call result:</label>
<code id="status" style="margin:10px;display:block;white-space:pre-wrap;"></code>
<script>
// CLICK handler on button
jQuery("#button").click(function (event)
{
var myObject =
{
Firstname: "Darth",
Lastname: "Vader",
"Birth day": new Date(1966, 6, 6),
};
jQuery("#content").load("handler1.ashx",
myObject,
function (response, statusText, jqXHR)
{
if ("success" == statusText)
jQuery("#status").text("SUCCESS:\r\nResponse:\r\n" + response);
else
jQuery("#status").text("PROBLEM:\r\nstatusText: " + statusText
+ "\r\nResponse:\r\n" + response);
}
);
});
</script>
Looking like this:
More often than not, there is a need to send data entered by the user to the server, in other words from form fields. You could go ahead and collect the data from the relevant form fields. But jQuery exposes a method that does just that:
The serialize method collects data from the elements contained in the jQuery set. Actually, only elements that would contribute in a normal form POST, such as input, select or textarea element types are considered. The
name attribute of the element forms the name part of the parameter.
The method has the format jQuerySet.serialize()
, and it returns a formatted, encoded query string. Using the output from the serialize method for the load method results in a GET request,
since the method returns a string.
An example, still using the same server method to echo the request:
<fieldset id="fields">
<label>Firstname:</label> <input name="firstname" />
<label>Lastname:</label> <input name="lastname" />
<label>Alive:</label> <input name="alive" type="checkbox" />
<label>Genius:</label> <input name="genius" type="checkbox" />
<label>Male:</label> <input name="gender" type="radio" value="male" />
<label>Female:</label> <input name="gender" type="radio" value="female" />
<button id="button">Send data</button>
</fieldset>
<label>Response:</label>
<div id="content" style="margin:10px;"></div>
<script>
// CLICK handler on button
jQuery("#button").click(function (event)
{
jQuery("#content").load("handler1.ashx", jQuery("#fields").serialize());
});
</script>
It is evident from the screenshot below, that unchecked checkboxes and radios are not sent with the request.
One way to fix this, if needed, is to use the serializeArray method instead of serialize and then to add the parameter if the checkbox is not checked. Since a checkbox sends the value on if it's checked, it makes sense to use the value off for the non-checked state:
var array = jQuery("#fields").serializeArray();
jQuery(":checkbox").each(function () {
if (!this.checked)
array.push({ name: this.name, value: "off" });
});
jQuery("#content").load("handler1.ashx", array);
The serializeArray (see previous example code) method collects data from the elements contained in the jQuery set. As for the serialize method, only elements that would contribute in
a normal form POST, such as input, select or textarea element types are considered. The
name attribute of the element forms the name part of the parameter.
The method has the signature jQuerySet.serializeArray()
, and it returns an array of objects with a name and value property, which jQuery then uses to populate the request.
Using the output from the serializeArray method for the load method results in a POST request,
since the method returns an array of objects.
The load in some cases makes a GET request, and in other cases does a POST, depending on what type of input data it is fed with. jQuery also exposes methods that allow for a more fine-grained control of the request:
The get method performs an Ajax GET request and has the signature jQuery.get(url [, data] [, onSuccess] [, dataType])
, returning a jqXHR object. Note that this is a method
on the global jQuery object - it does not operate on a jQuery set like the loadMethod. This means there is no "automatic" injection of the Ajax response into the DOM, but that can be done in the onSuccess callback
instead.
Name | Type(s) | Description |
url | String | url address. |
data | String/object | The data to send in the request. May be a preformatted string of url parameters. Or it can be an object whose properties will get serialized to form the query string. |
onSuccess | function(response, statusText, jqXHR) | A callback function to be called when the request returns with success.
The function context is set up to reference an object with properties that represent the options of the Ajax request. The callback takes these parametes:
|
dataType | String | The data type of the expected server response. May be text, xml, script, json, jsonp or text. jQuery will make a qualified guess as to the type if this parameter is omitted, based on the MIME type of the server response. The data type determines how jQuery will process the result and what the response parameter in the onSuccess callback will contain. |
I modified the above example to use the get method:
<button id="button">Send data</button>
<label>Response:</label>
<div id="content"></div>
<script>
// CLICK handler on button
jQuery("#button").click(function (event)
{
var myObject =
{
Firstname: "Niels",
Lastname: "Bohr",
Child:
{
Firstname: "Aage",
Lastname: "Bohr",
},
};
var jqXHR = jQuery.get("handler1.ashx", myObject,
function (response, statusText, jqXHR) {
jQuery("#content").html(response);
}).fail(function (jqXHR) {
jQuery("#content").html("status: " + jqXHR.status + ", statustext: " + jqXHR.statusText);
});
});
</script>
Responding with:
This example demonstrates how to handle errors: by attaching a handler function via the fail method of the jqXHR object returned from the get method. It might seem a little strange to assign an error handler after the call has been made, but remember that Ajax is asynchronous, so the call of the get method returns immediately. In addition to the fail callback, you can assign done (success) and always (success or error) callbacks, all of which get called when the Ajax request terminates. The fail, done and always handlers takes the jqXHR instance as the single parameter, which can be used to enquire about the result of the Ajax call, as in the example.
One other thing to take away from the above example is how the input data get serialized, specifically the Child.Firstname property is assigned the name Child[Firstname].
The above examples receive plain text or html from the server. When the server responds with xml, jQuery sets the response parameter of the onSuccess callback to reference a XmlDocument instance, which is the result or serializing the response from the server. I modified the server method to return this bit of xml, setting the content type to "text/xml":
<Person>
<age>9</age>
<name>Bentsen</name>
</Person>
Now, the following example outputs some data from the xml document:
<button id="button">Send data</button>
<label>Response:</label>
<div id="content"></div>
<label>Ajax call result:</label>
<code id="status" style="margin:10px;display:block;white-space:pre-wrap;"></code>
<script>
// CLICK handler on button
jQuery("#button").click(function (event)
{
var jqXHR = jQuery.get("handler1.ashx", "",
function (response, statusText, jqXHR) {
jQuery("#content").html("Name: " + response.documentElement.childNodes[1].innerHTML
+ ", aged " + response.documentElement.childNodes[0].innerHTML);
}).fail(function (jqXHR) {
jQuery("#content").html("status: " + jqXHR.status + ", statustext: " + jqXHR.statusText);
});
});
</script>
The post method performs an Ajax POST request and has the signature jQuery.post(url [, data] [, onSuccess] [, dataType])
, returning a jqXHR object. This method works exactly like the get
method, except that a HTTP POST is performed instead of a GET, so please refer to the description of that method above.
If you know that the server method returns json data, you can use the getJSON method, and have jQuery deserialize the returned data for you. This method is just syntactic alias for the get method, and so makes
a HTTP GET request. The method has the signature jQuery.getJSON(url [, data] [, onSuccess] [, dataType])
, returning a jqXHR object. For a description of the parameters,
please refer to the description of the get method above. The returned json object is available through the response argument of the onSuccess callback.
I changed the server method to return a very simple json object with age and name properties. In the next example, the two properties of the json object are written to the DOM:
<button id="button">Send data</button>
<label>Response:</label>
<div id="content"></div>
<script>
// CLICK handler on button
jQuery("#button").click(function (event)
{
var jqXHR = jQuery.getJSON("handler1.ashx", "",
function (response, statusText, jqXHR) {
jQuery("#content").html("Person " + response.name + ", aged " + response.age);
}).fail(function (jqXHR) {
jQuery("#content").html("status: " + jqXHR.status + ", statustext: " + jqXHR.statusText);
});
});
</script>
The methods described above internally call the ajax method. If you need full control of ther Ajax request, you can call this method directly. The signature of the method is deceptively simple:
jQuery.ajax([url] [, options])
, returning a jqXHR object. The catch is that the options parameter is an object with a wealth of properties, allowing one to control the Ajax request
in full detail. These are the parameters of the ajax method:
Name | Type(s) | Description |
url | String | url address. This argument can be omitted, in which case the url must be specified in the options object instead. |
options | object | An object containing the data to send in the request and properties to control the Ajax request. |
I am not going to describe the full set of properties of the options object, but these are probably the more important ones:
Name | Type(s) | Description |
url | String | url address. |
method | String | The HTTP method to use, e.g. GET, POST, PUT, etc. Default is GET. |
data | String/object/object[] | The data to send in the request. May be a preformatted string with url parameters. It can also be an object whose properties will get serialized or an array of objects having name and value properties. |
dataType | String | The data type of the expected server response. May be text, xml, script, json, jsonp or text. jQuery will make a qualified guess as to the type if this parameter is omitted, based on the MIME type of the server response. The data type determines how jQuery will process the result and what the response parameter in the success callback will contain. This property can also be a string of space-separated values, in which case jQuery will convert one data type to another. For example, if the response is text, it will be converted to xml, if dataType specifies "text xml". |
cache | Boolean | Determines if the browser caches the response for GET requests. The default is true. |
success | function | Callback(s) to be called when the request succeeds. The function context is set up to reference an object with properties that represent the options of the Ajax request. The callback takes these parameters:
|
error | function | Callback(s) to be called when the request fails. The function context is set up to reference an object with properties that represent the options of the Ajax request. The callback takes these parameters:
|