Introduction to AJAX
Introduction to AJAX
Introduction to the Asynchornous JavaScript + XML
Overview
Asynchronous JavaScript And XML, which is AJAX or Ajax, is a set of techniques used to deal with data between a webpage and a webserver. Despite the presence of JavaScript in the name, Ajax is neither a language nor a library; it is a means of using JavaScript for Web requests. Despite the presence of "XML" in the name, AJAX techniques can be used to deal with any type of text-based file.
Although Ajax is not a language, the techniques it presents provide two valuable advantages:
Practical Learning: Introducing .NET Collection Classes
body { background-color: #2b5b8f; } .bold { font-weight: 600; } .xsmall { width: 60px; } .small { width: 100px; } .medium { width: 150px; } .large { width: 200px; } .xlarge { width: 400px; } .ctl-deco { color: #cfdde0; } .wm-contents { margin: auto; width: 500px; } .top-bar { top: 0px; height: 7em; width: 100%; position: fixed; background-color: #203864; } .logo-bar { margin: auto; width: 460px; } .navbar-inverse { background-color: #001132; border-top: 3px solid #cfdde0; border-bottom: 3px solid #cfdde0; } .navbar-fixed-top { top: 6.75em; } .jumbotron { padding-bottom: 4px; background-color: #153a62; } .col-md-4 h2 { color: #abcbd9; border-bottom: 1px solid #cfdde0; } .highligh { width: 100%; color: white; background-color: #203864; border: 1px solid white; } .lead { color: #cfdde0 } .col-md-4 p { color: #d5d4c2; } .copyright { color: #beeeab; } .push-down { margin-top: 8em; } .push-down h2 { color: #d5d4c2; } .push-down h3 { color: #abcbd9; } .push-down p { color: #cfdde0; } .push-down2 { margin-top: 4em; } .left-col { width: 100px } .ctl-deco { font-weight: 600; color: #cfdde0; } .large-col { width: 170px; font-weight: 600; color: #cfdde0; } .xlarge-col { width: 430px; font-weight: 600; color: #cfdde0; } address { color: #cfdde0; }
using System.Web;
using System.Web.Optimization;
namespace WaterDistribution1
{
public class BundleConfig
{
// For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css",
"~/ Content / WaterDistribution.css"));
}
}
}
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - Water for a Shining Life</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="top-bar"> <div class="logo-bar"><img src="~/Images/wsl1.png" alt="Water for a Shining Life" width="490" height="92" /></div> </div> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("Home", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("Emergency Services", "Index", "Home")</li> <li>@Html.ActionLink("Cummunity", "Index", "Home")</li> <li>@Html.ActionLink("Environment", "Index", "Home")</li> <li>@Html.ActionLink("Resources", "Index", "Home")</li> <li>@Html.ActionLink("Projects", "Index", "Home")</li> <li>@Html.ActionLink("Customer Service", "Index", "Home")</li> <li>@Html.ActionLink("Employment", "Index", "Home")</li> <li>@Html.ActionLink("Questions?", "Index", "Home")</li> <li>@Html.ActionLink("About", "About", "Home")</li> <li>@Html.ActionLink("Contact", "Contact", "Home")</li> </ul> </div> </div> </div> <div class="container body-content"> @RenderBody() <hr /> <footer> <p class="copyright text-center">© @DateTime.Now.Year - Water for a Shining Life</p> </footer> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>
@{ ViewBag.Title = "Welcome"; } <div class="jumbotron"> <h2>.</h2> <p class="lead">Our water utility company provides energy, greatness, and warmth for a everyday life, a shining life. We provide solutions to families, businesses, and the community.</p> <p class="lead">This is the employees portal section of the company. From here, employees can register a new water meter, manage a customer account, or create a water bill.</p> </div> <div class="row"> <div class="col-md-4"> <h2>Water Meters</h2> <p>Our company uses the most accurate, sophisticated, and environment-friendly water meters on the market. Our suppliers care.</p> <p>@Html.ActionLink("Create Water Meter", "CreateWaterMeter", "BillsProcessing", new { @class = "btn btn-primary" })</p> </div> <div class="col-md-4"> <h2>Customers</h2> <p>We supply water to individuals, families, small businesses, as well as enterprises or government agencies.</p> <p>@Html.ActionLink("Create Customer Account", "CreateCustomerAccount", "BillsProcessing", new { @class = "btn btn-primary" })</p> </div> <div class="col-md-4"> <h2>Water Bills</h2> <p>Our water rates are very competitive nationwide. We use precise, effective, and strict algorithms when performing our water bills calculations.</p> <p>@Html.ActionLink("Create Water Bill", "WaterBillStartUp", "BillsProcessing", new { @class = "btn btn-primary" })</p> </div> </div>
<?xml version="1.0" encoding="utf-8" ?> <water-meters> <water-meter> <meter-number>293-740</meter-number> <make>Breston</make> <model>S-93749</model> <meter-size>3/4 Inches</meter-size> </water-meter> <water-meter> <meter-number>820-418</meter-number> <make>Vashty Worldwide</make> <model>DD-3840</model> <meter-size>3/4 Inches</meter-size> </water-meter> </water-meters>
using System.Web.Mvc;
namespace WaterDistribution1.Controllers
{
public class CustomersController : Controller
{
// GET: Customers
public ActionResult Index()
{
return View();
}
// GET: Customers/Create
public ActionResult Create()
{
return View();
}
}
}
An HTTP Request
To support the various types of document requests to the server, the DOM provides a class named XMLHttpRequest. Once again, the presence of "XML" in the name doesn't mean a restriction on the types of files that can be made available. The XMLHttpRequest class is practically the central point of Ajax.
To let you create objects, the XMLHttpRequest class is equipped with a default constructor. As is the case for all non-static classes we have used so far, to get an XMLHttpRequest object, declare a variable and initialize it with this class using the new operator. Here is an example:
var xhrService = new XMLHttpRequest();
As is usually the case on the Internet, not all browsers support the XMLHttpRequest class or not all of them support it the same way. This means that, although most browsers support it, they may exhibit different behaviors, and sometimes the behaviors depend on the way the request is made.
Sending a Request
After formulating a request, when you are ready, you must send it to the webserver. To let you send the request, the XMLHttpRequest class is equipped with a method named send. Its syntax is:
send(body = Object);
This method takes an argument that is optional. The argument can be an object of type Document if you want the server to serialize the document before sending it. Here is an example of calling this method:
var xhrService = new XMLHttpRequest();
xhrService.send();
The Status of a Document
To respond to your request, the server must check the status of the document and act accordingly. To support this, the XMLHttpRequest class is equipped with a property named status. This is a standardized positive integer known as the HTTP Status Code. There are many code values available, they mean different things, and the server reacts differently depending on the status code. Some of the most common values are:
Value | Status | Description |
200 | OK | The request is/was successful. The value actually depends on the form method that was applied (POST, GET, PUT, or TRACE) |
201 | Created | The request was successful and a document was created |
400 | Bad Request | The webserver doesn't understand the request. This means that the request is probably badly formulated |
401 | Unauthorized | Although this response can mean anything or many things, the user probably didn't provide valid credentials (username and password) to access the document |
403 | Forbidden | Although this response can mean anything or many things, at first glance, the user is probably not allowed to access the document |
404 | Not Found | The webserver did not or cannot find the requested document, for any reason (maybe there is no such a document at all or you made a mistake in the name or path of the document, maybe the document was previously renamed or moved, etc). This is probably the most popular and the most concerned of all errors |
408 | Request Timeout | For any reason, it was taking the webserver too much time to fulfill the request or find the document. If this happens, the server is configured to stop (or postpone) searching and let you know |
409 | Conflict Timeout | For any reason, the webserver has concluded that this request conflicts with its work and therefore cannot be fulfilled |
414 | URI Too Long | Either the file name or the path is too long for the webserver to process, analyze, interpret, or understand it |
Opening a Document
To let you specify the document you want to open, the XMLHttpRequest class is equipped with a method named open. The method takes two required arguments and three optional arguments. Its syntax is:
XMLHttpRequest.open(method, url, async = true, user = null, password = null);
The first argument is the type of method we have used on forms in previous lessons. Use it in uppercase (POST, GET, PUT, DELETE, etc). The second argument is the name or the path of the file you want to open. Here is an example of calling this method:
var xhrService = new XMLHttpRequest();
xhrService.open("POST", "~/App_Data/Service.txt");
xhrService.send();
The third argument is a Boolean value that specifies whether the operation should be performed asynchronously. The default value is true. The fourth and the fifth arguments are used if the user must provide credentials used to validate permissions to open the document. Their default values are null. If you don't have these values, don't pass them or pass each as null.
Getting Ready for an HTML Response
When you have made a request, the webserver responds one way or another. To let you prepare for a response, the XMLHttpRequest class is equipped with a read-only property named onreadystatechange. This property is of type EventHandler. The XMLHttpRequest.onreadystatechange property expects a callback function:
XMLHttpRequest.onreadystatechange = callback-function
To use this property, you can define a function and assign it to the property. This can be done as follows:
var xhrService = new XMLHttpRequest();
xhrService.onreadystatechange = function () {
}
xhrService.open("GET", "Service.txt", true);
xhrService.send();
Or you can first define a function and then assign it to the XMLHttpRequest.onreadystatechange property.
The Current State of the Request
When the webserver receives a request to open a document, it wants to know the current status of the webpage as far as the operation is concerned. To support this status, the XMLHttpRequest class is equipped with a read-only property named readyState. The readyState property holds a value that is a static constant member of the same class. This means that the value is provided like those of an enumeration and the enumeration is named XMLHttpRequest. The members and values are:
Member | Value | Description |
DONE | 4 | The operation is complete.
Use one of the values or members in a conditional statement formulated in the callback function to find out the state of the request. You can specify the value from its constant. Here is an example: var xhrService = new XMLHttpRequest();
xhrService.onreadystatechange = function () {
if (xhrService.readyState == 4) {
. . .
}
else
alert("The document is not ready");
};
xhrService.open("GET", "Service.txt", true);
xhrService.send();
Or you can qualify the member using the name of the class. Here is an example:
var xhrService = new XMLHttpRequest();
xhrService.onreadystatechange = function () {
if (xhrService.readyState == XMLHttpRequest.DONE) {
. . .
}
else
alert("The document is not ready");
};
xhrService.open("GET", "Service.txt", true);
xhrService.send(); |
UNSENT | 0 | The request has been created but it has not (yet) been sent |
OPENED | 1 | The XMLHttpRequest.open() method has been called |
HEADERS_RECEIVED | 2 | The XMLHttpRequest.send() method has been called |
LOADING | 3 | The requested document is currently being downloaded |
Because the status of the document can also be an issue, you can use a Boolean conjunction to also check the HTTP Status Code of the document. Here is an example:
var xhrService = new XMLHttpRequest();
xhrService.onreadystatechange = function () {
if( (xhrService.readyState == XMLHttpRequest.DONE) && (xhrService.status == 200) ) {
. . .
}
// else
// alert("Something went wrong");
};
xhrService.open("GET", "Service.txt", true); // "Service.txt", true);
xhrService.send();
Introduction to Accessing an Ajax Document
Ajax deals with any text-based document, including webpages, etc. To let you read the whole content of the document as one object, the XMLHttpRequest class is equipped with a read-only property named responseText, which is a string. If you want to display it in a webpage, you can pass it to a web control or pass it to a document.write() method. Here is an example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise: Service</title>
</head>
<body>
<script type="text/javascript">
(function showMessage() {
var xhrService = new XMLHttpRequest();
xhrService.onreadystatechange = function () {
if (xhrService.readyState == XMLHttpRequest.DONE && xhrService.status == 200) {
document.write(xhrService.responseText);
}
};
xhrService.open("GET", "Service.txt", true);
xhrService.send();
})();
</script>
</body>
</html>
If the document is XML, to let you open and analyze it, the XMLHttpRequest class is equipped with a read-only property named responseXML. This property produces a Document object:
Document responseXML;
The Document interface contains all of the methods and properties you can use to get the various nodes or elements in the document. You can then use XPath to find any node in the document.
Fundamentals of XML in Ajax
Introduction
When creating a Web project, you can use XML to create, manage, and maintain data for your website. As we saw in the previous lessons and we will see in this and the next lessons, XML offers a complete database solution.
If you have a background in Windows application programming (Win32, desktop solutions, C++, Delphi, Visual Basic, ASP.NET Web Forms, F#, Java, etc), you are probably familiar with controls events. ASP.NET MVC doesn't support events, at all (ASP.NET Web Forms supports a few events). As we saw in previous lessons, the only notification (notifications are the basis for events) you can send to a webserver is that one ore more values have been posted. With ASP.NET MVC, you can't even tell the webserver how (or why) the value(s) has (have) been posted. Since you can use only a Submit notification, any control that has a click (or change) event (a radio button, a check box, an HTML Submit button) can send that single notification but the webserver has no way to identify who (or what) sent that notification.
Both the JavaScript language and its many libraries, which include jQuery, support events. Fortunately, you can use those libraries in your ASP.NET MVC project. You can use Ajax to open an XML file, read its content and use it in your ASP.NET MVC webpage. This allows you to use the JavaScript and/or jQuery events in the webpage.
Introduction to Ajax in jQuery
To support Ajax in jQuery, the $ namespace of the library includes a method named ajax. Therefore, to call this method, attach it to its namespace, as in $.ajax(). The method takes one required and many optional arguments. The first argument is an object that holds the information, called configuration, of how the Ajax operation will be carried. You can first define the object and then pass it as argument to the method. This can be done as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/jquery-1.10.2.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function () {
var connection = {};
$.ajax(connection);
});
</script>
</body>
</html>
Or you can define the object directly in the parentheses of the $.ajax() method. If you don't want to specify the whole object of the $.ajax(), the $ namespace provides various alternatives.
Primary Characteristics of Ajax in jQuery
The Method to Request Data
As seen in our early introductions, Ajax supports varius types of operations that include requesting, sending, editing, or deleting data. When formulating a request, you must indicate yor intentions to the webserver. To support this, the object of the $.ajax() method includes a property named type. Set the desired HTML method as the value of this property. The value is specified as a string. Here is an example:
$(document).ready(function () {
var connection = { type: "GET" };
$.ajax(connection);
});
The XML to Use
To use XML in your Ajax operation, you have two primary options. If you want to use XML in memory, create XML code and include in a string. Declare a variable and assign the XML code to it. If your XML is in a file, to let you specify it, the object of the $.ajax() is equipped with a property named url. Set the name or path of the file to this property. Here is an example:
var connection = {
type: "GET",
url: "WaterMeters.xml"
};
$.ajax(connection);
The Type of the Data of a Request
Again, Ajax supports various types of data, including text, HTML, etc. To let you specify the type(s) of the value(s) involved in the Ajax request, the object of the $.ajax() method is equipped with a property named dataType. Assign the type of value(s) involved in the Ajax operation. The values is specified as a string. Some of the available data types are text, html, and script. If you are using XML, specify the type as such. Here is an example:
var connection = {
type: "GET",
url: "WaterMeters.xml",
dataType: "xml"
};
$.ajax(connection);
Successfully Processing a Request
When presenting an Ajax request to a webserver, the way you process the request depends on the method you chose, whether you are sending data to the webserver or getting data from it. To let you process the successful outcome of the request, the object of the $.ajax() method is equipped with a method named success. Create it as a property of that name. The value of the property must be a callback function. The method takes one argument which is an object that holds the data involved in the Ajax request. It can start as follows:
var connection = {
type: "GET",
url: "WaterMeters.xml",
dataType: "xml",
success: function (data){
}
};
$.ajax(connection).done(function (argument) { });
In the body of themethod, get the data from its argument. You can then use your knowledge of JavaScript and jQuery to get, check, validate, process, and perform any type of operation on the nodes of the XML object or file.
Practical Learning: Opening an XML File in Ajax
@{ ViewBag.Title = "New Customer Account"; } <div class="push-down"> <h2 class="text-center">New Customer Account</h2> </div> <hr /> <div class="wm-contents"> <form name="CustomerAccount" method="post"> <table> <tr> <td class="small ctl-deco"><label for="acntNbr">Account #:</label></td> <td><input type="text" name="AccountNumber" id="acntNbr" class="form-control large" /></td> </tr> </table> <table> <tr> <td class="small ctl-deco"><label for="mtrNbr">Meter #:</label></td> <td><input type="text" name="MeterNumber" id="mtrNbr" class="form-control small" /></td> <td><input type="text" id="btnFindWaterMeter" value="Find" class="btn btn-primary xsmall" /></td> </tr> </table> <table> <tr> <td class="small"> </td> <td><input type="text" id="mtrDetails" class="form-control xlarge" /></td> </tr> </table> <table> <tr> <td class="small ctl-deco"><label for="fName">First Name:</label></td> <td><input type="text" name="FirstName" id="fName" class="form-control small" /></td> <td class="ctl-deco"><label for="lName"> Last Name:</label></td> <td><input type="text" name="LastName" id="lName" class="form-control small" /></td> </tr> <tr> <td class="ctl-deco"><label for="mtrNbr">Address:</label></td> <td colspan="3"><input type="text" name="Address" class="form-control xlarge" /></td> </tr> <tr> <td class="ctl-deco"><label for="ct">City:</label></td> <td><input type="text" name="City" id="ct" class="form-control small" /></td> <td class="ctl-deco"><label for="local"> County:</label></td> <td><input type="text" name="County" id="local" class="form-control small" /></td> </tr> <tr> <td class="ctl-deco"><label for="state">State:</label></td> <td><input type="text" name="State" id="state" class="form-control small" /></td> <td> </td> <td> </td> </tr> </table> <hr /> <table> <tr> <td style="width: 120px"> </td> <td><input type="reset" name="btnReset" value="Reset" class="btn btn-primary medium" /></td> <td> </td> <td><input type="submit" name="btnSubmit" value="Submit" class="btn btn-primary medium" /></td> </tr> </table> </form> <table> <tr> <td>@Html.ActionLink("New Water Meter", "Create", "WaterMeters", new { @class = "navbar-brand" })</td> <td>@Html.ActionLink("Customer Bill Preparation", "Create", "WaterBills", new { @class = "navbar-brand" })</td> </tr> </table> </div> @Scripts.Render("~/bundles/jquery") <script type="text/javascript"> $(document).ready(function () { $("#btnFindWaterMeter").click(function (event) { $.ajax({ url: "/WaterDistribution/WaterMeters.xml", method: "GET", dataType: "xml", success: function (data) { var waterMeters = $(data).find("water-meter"); waterMeters.each(function () { if ($(this).find("meter-number").text() == $("#mtrNbr").val()) $("#mtrDetails").val($(this).find("make").text() + " " + $(this).find("model").text() + " (" + $(this).find("meter-size").text() + ")"); }); // Each Water Meter } // Success }); // Ajax }); // Click Event }); // Document.Ready </script>
A Shortcut to Get the Data
As a shortcut to perform an Ajax GET operation in jQuery, the $ namespace is equipped with a method named get. This method takes two arguments. The first argument is the name of the file and/or its path. The second argument is a callback function that will manage the request. The function takes as argument an object that holds the data of the transmission. Here is an example of calling this method:
<script type="text/javascript"> $(document).ready(function () { $("#btnFindWaterMeter").click(function (event) { $.get("/WaterDistribution/WaterMeters.xml", function (data) { var waterMeters = $(data).find("water-meter"); waterMeters.each(function () { if ($(this).find("meter-number").text() == $("#mtrNbr").val()) $("#mtrDetails").val($(this).find("make").text() + " " + $(this).find("model").text() + " (" + $(this).find("meter-size").text() + ")"); }); }); }); }); </script>
Other Configuration Options
The object of the $.ajax() method uses many more options than we reviewed above.
Processing a Request
Starting a Promising Request
The $.ajax() method works as a promise. As we saw in our introduction to promises in JavaScript, the $.ajax() method is a function that anticipates various outcomes, including a success, a failure, and an outcome that always occurs. The successful outcome is the place to process things that would go alright. The successful outcome is handled by a method named done. You can attach that method to the call of $.ajax(). The $.ajax().done() method takes a callback function as argument. That argument represents the data of the transmission. This can be formulated as follows:
$(document).ready(function () {
var connection = { };
$.ajax(connection).done(function (argument) { });
});
In this case, if data is being sent to the webserver, the argument holds that data. If the webserver is sending data to a browser, the argument is carrying that data.
Practical Learning: Processing a Successful Outcome
<script type="text/javascript"> $(document).ready(function () { $("#btnFindWaterMeter").click(function (event) { var connection = { url: "/WaterDistribution/WaterMeters.xml", method: "GET", dataType: "xml" }; $.ajax(connection). done(function (data) { var waterMeters = $(data).find("water-meter"); waterMeters.each(function () { if ($(this).find("meter-number").text() == $("#mtrNbr").val()) $("#mtrDetails").val($(this).find("make").text() + " " + $(this).find("model").text() + " (" + $(this).find("meter-size").text() + ")"); }); }); }); // Click Event }); // Document.Ready </script>
A Failing Promise
The failure outcome is used if you think that there is a possibility that the Ajax operation would not be honored. This outcome is handled by a method named fail. If used, attach this method to the done() call. The fail() method takes three arguments. The first is the HXMLHttpRequest object that carried the request. The second argument is the HTTP status code that specifies the failure and why it occurred. The third argument is the error that was produced.
Practical Learning: Processing a Successful Outcome
. . . No Change <p style="text-align: center; color: aliceblue;" id="errorMessage"></p> @Scripts.Render("~/bundles/jquery") <script type="text/javascript"> $(document).ready(function () { $("#btnFindWaterMeter").click(function (event) { var connection = { url: "/App_Data/WaterMeters.xml", method: "GET", dataType: "xml" }; $.ajax(connection). done(function (data) { var waterMeters = $(data).find("water-meter"); waterMeters.each(function () { if ($(this).find("meter-number").text() == $("#mtrNbr").val()) $("#mtrDetails").val($(this).find("make").text() + " " + $(this).find("model").text() + " (" + $(this).find("meter-size").text() + ")"); }); }). fail(function (xhr, status, error) { $("#errorMessage").text("Error Request: " + xhr + "; Status Code: " + status + "; Error Handled: " + error); }); }); // Click Event }); // Document.Ready </script>
A Permanent Outcome
The last outcome is named always. Like its name suggests, this section is always executes regardless of what happens in the Ajax operation. The always outcome is created like a function. Attach it to the previous fail() call. The always() method takes two arguments which are the same of the first two arguments of the fail() method. As a result, to call all three methods, use the following formula:
$.ajax( configuration ).done(function (argument){. . . }).fail(function (XMLHttpRequest-argument, status, erroe){ }).always(function (XMLHttpRequest-argument, status){ });
Practical Learning: Ending the Lesson
|
||
Previous | Copyright © 2017-2022, FunctionX | Next |
|