Skip to main content

End-to-end Ajax application development, Part 2: Implement the Ajax client and server tiers

Separate your application tiers to produce a clean and elegant Web app

Senthil Nathan (sen@us.ibm.com), Senior Software Engineer, IBM
Photo of Senthil Nathan
Senthil Nathan is a senior software engineer at the IBM T.J. Watson Research Center in Hawthorne, New York. He has 23 years of experience in building software for different kinds of enterprise applications. His current professional interests are fully buzzword-compliant -- including SOA, Web services, Stream programming, Java 2 Platform, Enterprise Edition (J2EE), PHP, Ruby On Rails, Web 2.0, and Ajax development.

Summary:  Ajax (Asynchronous JavaScript + XML) is quickly emerging as a modern way of bringing desktop quality software features to Web applications running on browser platforms. This article is second of a three-part series where you can continue learning about developing an end-to-end Ajax application using technologies available from the open-source community.

View more content in this series

Date:  19 Jun 2007
Level:  Intermediate
Activity:  204 views

In Part 1 of this three-part series, you learned about the salient features of open source technologies such as Firefox, Zend Core, and MySQL. You were introduced to a non-trivial bank scenario that spans across all three tiers of an Ajax application. You also set up the database server, mid-tier server, and Eclipse-based IDE, which are required for end-to-end Ajax application development. In this second part of the series, you will develop some portions of the bank scenario. In particular, you'll create a back-end database using the MySQL database. You'll get exposure to several MySQL command-line tools for connecting, creating, defining, and populating bank-specific data in the database. Then, you will develop a mid-tier PHP module to house the bank's business logic, which uses ODBC to connect to the MySQL database. Finally, you'll develop a bank portal to provide a simple browser UI through which users can interact with this end-to-end application, which will soon be ready to run on Zend Core.

Introduction

As discussed in Part 1, the bank scenario centers around providing basic account services that bank tellers perform. If you haven't already, you should study the scenario as described in Part 1. To start with, customer data is an important part of this scenario. For the purposes of this exercise, all customer data will be populated in the database table at once. After this, the stored customer data can be retrieved and updated through the ODBC MySQL driver provided with Zend Core. Once the customer data is taken care of, the focus shifts to the core bank logic that is required to provide the bank teller functions. You will develop a PHP code module to provide the core bank logic with the necessary database access using ODBC. The main advantage of using Zend Core and PHP for this logic is to make use of the built-in support for MySQL.

After performing the database and PHP module work, you will continue with providing a simple user interface for the bank tellers to perform the four core functions. As described in the scenario, the core bank logic encapsulated in the PHP module will be accessed through a thin client. Specifically, this Web-based thin client will be generated in the Ajax style: XHTML, Cascading Style Sheets (CSS), JavaScript, and XMLHttpRequest (XHR). It will provide a simple user interface for bank tellers to perform core bank actions. This browser UI will also demonstrate a specific method by which the browser client logic will communicate over the network with the server-side logic in PHP.

The Ajax techniques used to design a browser application make the application highly responsive to user interactions. They also relieve the server from the heavy load of mundane page fetches. In Ajax applications, browser-to-server interactions come down to only application-specific data interchanges, which results in optimizing server resources to more users and more applications. Read on to learn a few basic techniques that introduce you to the concepts behind building a single-page browser application.

At the end of this part of the series, you will have built the database, a PHP module for the core bank logic, and a single-page based browser user interface, which are all part of our bank scenario.

MySQL database

As you learned in Part 1, MySQL is an open source database. In our scenario, you use the community server edition, which is a compact database server with many useful features. Because the bank scenario implementation is based on open source products, MySQL is a nice fit to go with the Zend Core PHP server. MySQL is supported in Zend Core out of the box. There are various tools that support MySQL administration and programming. In our scenario, you will use only the MySQL command-line client to perform the administration of MySQL. You will create the bank accounts database for our scenario using the MySQL database.

Create and populate the bank database

In this scenario, you'll store the account information for a given customer using the following details:

  • AccountHolderName
  • AccountNumber
  • CheckingBalance
  • StockName
  • StockQuantity
  • StockValue

Account information for a given customer contains the name of the account holder, an account number, the current checking balance, a ticker symbol of a single stock that the customer owns, the total number of stock units held, and the current market value of that stock portfolio. The following sections give you detailed steps on how to create a database table and then populate the table with account details for some fictitious bank customers. Let's get started!

Follow these steps to create the database and then populate the table with application-specific data:

  1. If it is not running already, start Eclipse (c:\eclipse\eclipse.exe).
  2. Ensure that PHP is the active perspective in Eclipse:
    1. Select Window->Open Perspective->Other->PHP and click OK.
  3. In Eclipse, select File->New->Project.
  4. Select General->Project and click Next.
  5. Enter BankDB in the project name field.
  6. Click Finish.
  7. Right-click on BankDB project and select New->Other.
  8. Select General-> File and click Next.
  9. In the File name field, enter BankDB.sql and click Finish.
  10. Enter or paste the code contents for BankDB.sql as shown in Listing 1.
  11. Save and close the file.
  12. To start the MySQL command line client, click Windows Start Menu->All Programs->MySQL->MySQL Server->MySQL Command Line Client.
  13. In the MySQL command line window, type the password as webtech and press Enter.
  14. At the mysql> prompt, type source c:\eclipse\workspace\BankDB\BankDB.sql and press Enter.
  15. Ensure that the previous command worked correctly by checking for the existence of the BankDB database. You can verify by typing the following commands:
    1. show databases;
    2. use bankdb;
    3. show tables;
    4. describe account;
  16. In the MySQL command line client, type exit to close it.

Listing 1. Contents of BankDB.sql file
			
-- This file is part of the End-to-End Ajax development article in
-- the IBM developerWorks. This file contains a simple DB script to
-- create a database and populate it with the data.
-- 
-- Last Modified: May/10/2007
-- 
-- To execute the following statements in MySQL, do the following steps.
-- 1) Start MySQL command line client.
-- 2) Enter your MySQL admin password.
-- 3) Type the following line by substituting <YOUR_SQL_FILE_DIR> with the
--    directory name where the file is stored.
--    source <YOUR_SQL_FILE_DIR>\bankdb.sql

--
-- Table structure for table 'BankDB'
--

DROP DATABASE BankDB;

CREATE DATABASE BankDB;

USE BankDB;

CREATE TABLE account (
   AccountHolderName VARCHAR(20) NOT NULL, 
   AccountNumber INTEGER NOT NULL,
   CheckingBalance DOUBLE NOT NULL,
   StockName VARCHAR(6),
   StockQuantity INTEGER,
   StockValue DOUBLE,
   PRIMARY KEY(AccountHolderName, AccountNumber)
);

--
-- Populating data for table 'account'
--

insert into ACCOUNT values ('Frodo', 435245, 2344.45, 'GOOG', 100, 3453.32);
insert into ACCOUNT values ('Sam', 928462, 7583.32, 'CSCO', 200, 5323.43);
insert into ACCOUNT values ('Pippin', 234233, 3444.62, 'INTC', 300, 4213.76);
insert into ACCOUNT values ('Merry', 642445, 1005.32, 'MSFT', 250, 1353.32);
insert into ACCOUNT values ('Aragorn', 972321, 6424.24, 'HPQ', 525, 12043.94);
insert into ACCOUNT values ('Gandalf', 432134, 5392.23, 'IBM', 400, 10043.78);
insert into ACCOUNT values ('Legolas', 590134, 4313.82, 'DELL', 325, 5926.62);
		

Using PHP to access the MySQL database

One of the popular features of PHP is its simple and classic support to access data stored in databases from different vendors, including MySQL. It provides an effective and easy method to integrate the business logic with databases. In the past few years, the PHP community made several improvements, such as PHP Data Objects (PDO), which provides an abstraction layer that exposes common API functions regardless of which database server is used. PHP database API functions are also made available in procedural style and in an object-oriented style. In this scenario, to get a basic understanding, you use the direct database API targeted for MySQL. PHP offers two ways to access MySQL:

  • MySQL
  • MySQL Improved

The regular MySQL extension doesn't support the full functionality of MySQL 4.1.0. These features include stored procedures, triggers, and views. The MySQL Improved (mysqli) extension is the latest and improved way to access those functions. An extension for mysqli is available in PHP 5.0 or above. However, mysqli is not enabled by default -- you have to enable it using the Zend Core administration tool. In this exercise, mysqli was already enabled in Part 1, when you installed and configured Zend Core.

One of the nice features of PHP database APIs is that they can map the result of a database operation in many different ways to PHP data structures. In other words, there are database APIs in PHP that can return the database results as a PHP associative array where the database table column names are the keys for that array. In another case, it can return the results as a PHP class object, where the database column names are the object properties. This is a very useful way to represent the results of the database queries.

Building blocks of PHP MySQLi functions

As previously mentioned, there is a vast array of mysqli functions available in PHP. To focus on our scenario, this section explains only the functions that are used in implementing the scenario. In particular, database functions such as connect, read, write, and release connection are covered here. For any additional details, refer to the PHP official documentation listed in Resources.

Before doing any database operation, you must establish a connection to a database server. In PHP, you use the following function to connect to a database:

$link = mysqli_connect("hostname", "user", "password", "dbname");

This function attempts to make a database connection to the specified database located on a specified host with proper credentials. There are other optional parameters that this function takes (refer to the PHP documentation). Upon successfully connecting to the database, this function returns a connection object, which is required in the subsequent database read and write operations. If the database connection attempt failed, then this function returns false. If you don't want to embed the database server password directly in your code as clear text, you might want to look at the MySQL password digest features.

A complementary function to the connect operation is the database close function:

$result = mysqli_close($link);

This function attempts to close the previously opened database connection. It takes the MySQL database connection object as a parameter and returns true if the database close operation was successful and false if it failed.

Having looked at connection management functions, let's look at the functions involved in reading from and writing to a database. The following is a list of useful functions in read/write operations:

  • (1) $result = mysqli_query($link, $queryStr);
  • (2) $numberOfRows = mysqli_num_rows($result);
  • (3) $row = mysqli_fetch_assoc($result);
  • (4) $row = mysqli_fetch_object($result);

Function (1) executes an SQL query on the database. It takes the connection object and a valid SQL query string as parameters. It executes and returns true on success or false on failure. However, for a SELECT SQL query, this function returns a result object.

Function (2) gets the number of rows in the result set returned from an SQL query. It takes the result object as a parameter.

Function (3) gets the result row as a PHP associative array. This array contains the database column names as the array keys and the database field values as the array values. For example, if a database query returned a value of a column named "capital," that result can be accessed by referencing the array with:

$stateCapital = $row['capital'];

Function (4) gets the result row as a PHP object. This object contains the database column names as object properties and the database field values as the object property values. For example, if a database query returned a value of a column named "park," that result can be accessed by dereferencing the object value with:

$nationalPark = $row->park;

As powerful as they are, Functions 3 and 4 also bring a very simple way to map database values to program variables. As mentioned earlier, PHP also offers several other ways to do database value mapping.

In our exercise, you'll be using two more functions to do error processing after a database operation. It is important to know if the intended database operation completed successfully or not. The following functions come in handy in dealing with that:

  • $returnCode = mysqli_errno($link);
  • $errorMsg = mysqli_error($link);

The mysqli_errno function returns the error code of the most recent function call. It takes the connection object as a parameter and returns the return code for the function that was executed. A return code of 0 indicates no error. The mysqli_error function returns a string description of the last error. Both these functions are essential to complete the full cycle of a database query.

Implementing the bank business logic in a PHP module

Follow these steps to create a PHP module and implement the mid-tier business logic:

  1. If you haven't already, switch to the Eclipse PHP perspective: click Window->Open Perspective->Other->PHP and click OK.
  2. Click File->New->PHP Project:
    1. In the Project name field, enter BankTeller.
    2. Click Finish.
  3. In the Project Explorer view, right-click the BankTeller project and select New->PHP File:
    1. In the File Name field, enter BankLogic.php and click Finish.
  4. Replace the contents of this file by entering or pasting the source code from Listing 2.
    1. Click File->Save to save the file.
  5. Review the comments in this file to understand the code or refer to the next section, which provides a high-level description about the code logic.

You can see how plain and simple it is to do database operations in PHP. You may notice in Listing 2 that the password is declared in clear text. It is a password used only in the test database you created for this article. You can improve it further by using the password as digest instead of clear text.

BankLogic PHP module logic

The PHP file in Listing 2 includes the business logic required for the core bank teller functions. In particular, these functions include getting all the account information stored in the database, performing deposit or debit transactions, and computing the stock portfolio value for a given customer. All these functions accept certain input parameters and return an application-specific associative array containing relevant account information. The bulk of the logic inside these functions involves connecting to the BankDB MySQL database and performing read or update-specific actions. Listing 2 defines three global-scoped PHP variables at the beginning. These variables store the database connection object ($link), the SQL query result object ($dbResult), and the final result ($finalResult) to be returned to the caller of this PHP module. This PHP module has two utility functions to connect to and disconnect from the MySQL database. When a connection is made, a connection object is created and stored in the $link variable, which is available throughout this PHP file because of its global scope. Similarly, when a DB read or update is performed, a SQL query result is stored in the $dbResult variable, which is also a global-scoped variable. When the database connection needs to be closed, the other utility function (close_connection_to_db) is used to disconnect from the database. Before closing the database connection, this utility function ensures that the memory occupied by the result set in $dbResult gets freed.

Three core functions are part of this file:

  • The getAllAccountInformation function is invoked by the caller to retrieve all the available account data stored in the database. The code here makes an ODBC connection to the MySQL database using MySQLi extension APIs and fetches all the account information stored in the account table. After a successful database read operation, it iterates on the result set and collects the individual account data information. It stores all the account data information in a PHP associative array and returns that array to the caller.
  • The accountTransaction function is invoked by the caller to perform either a deposit or debit operation. This method is called with parameters such as an account holder name, a transaction amount, and the transaction type to indicate if it is a deposit or debit operation. An ODBC connection is made to the MySQL database and the current account data for the given account holder is fetched from the database and stored in an associative array. This is the pre-transaction snapshot of this account. Then, the required transaction (deposit or debit) is performed. The database is updated with the new checking balance resulting from the money transaction. This post-transaction data is also stored in another associative array. Now, both the pre-transaction and post-transaction snapshots of the account are stored in a regular array and returned to the caller as the final result. Also notice that the code performs the transaction only if the transaction amount is valid for the intended transaction type.
  • The portfoliovalue method is invoked by the caller to compute the stock portfolio value of a given account holder name. This method is called with parameters such as an account holder name and the current stock price of the single stock that this account holder owns. This method takes a pre-transaction snapshot of the account data and stores it an associative array. It then computes the new total stock value and updates the corresponding database field in the Bank database. It also stores the post-transaction snapshot of the account data in another associative array. It stores both the account data snapshots in a regular array and returns them to the client as the final result.

The source file provides comments that will help you to understand the code logic.

Single-page Ajax user interface

For the bank teller user interface, you will develop a single-page browser application. Note that a single-page browser application is different from the traditional "Click and Wait" Web application. In the "Click and Wait" Web application, every Web page for that application is fetched from the server by downloading the entire page content every time, when the user navigates to a new page. On the other hand, the model behind a single-page browser application is exactly the opposite, where all the presentation content (XHTML, CSS, and JavaScript) required for an application is fetched only once from the server. This one-time download occurs typically at startup, when the user points the browser to an application URL. The XHTML file defines all the user interface elements required for an application. The CSS file codes all the styling required for different parts of the user interface. Special Document Object Model (DOM) techniques are applied to hide and show the relevant parts of the user interface, thereby simulating the multipage behavior without ever going to the server for another page fetch. Application-specific JavaScript code running on the browser can handle the majority of the application logic. The Ajax techniques used to design a browser application make the application highly responsive to user interactions. They also relieve the server from the heavy load of mundane page fetches. In Ajax applications, browser-to-server interactions come down to only application-specific data interchanges, which results in optimizing server resources to more users and more applications.

Beyond the benefits described here, there are other architectural concerns such as data security, data privacy, and appropriate partitioning of the business logic that can be trusted to run on the browser client. In addition, there is a need to recover from errors when an HTTP transaction is interrupted partway through. Such concerns are out of scope for this bank scenario article, which focuses only on implementing a single-page browser application with simple characteristics. Similarly, there are so many Ajax techniques that you can combine to provide rich graphics for a browser application. In this article, you'll look at only a few basic techniques that introduce you to the concepts behind building a single-page browser application.

One of the techniques used to hide and show different parts of a single-page browser application involves the use of <DIV>, <SPAN>, and <TABLE> HTML tags. Refer to Figure 1 for a simple overview of these tags. The <DIV> tag lets you divide the HTML document into separate sections. Placing the user interface controls of a specific screen inside a <DIV> tag is the first step in separating the many screens an application can have. Once it is done, through JavaScript, it is easy to manipulate which screen or <DIV> should be viewable at a particular stage in the execution of an application. Another tag that is handy in this exercise is the <SPAN> tag, which lets you apply styles to text segments in a browser application. In the bank scenario, you' use this tag to create menu control on a screen. In addition, you also use the <TABLE> tag to manage the document layout.


Figure 1. <SPAN>, <DIV>, <TABLE> Tags
HTML SPAN, DIV, TABLE Tags

Another common way to bring richness to browser applications is the ability to style at the level of individual user interface elements. CSS is widely used to manage the overall look of the browser applications. CSS is separate code with its own syntax. CSS is easy to set up because it doesn't need any plug-ins -- setup is all done in a text file by defining rules. A CSS rule consists of a selector and a declaration block. Selectors start each rule followed by a curly brace. The declaration block is surrounded by curly braces and made up of declarations. Declarations are pairs of properties and values separated by a semicolon. Listing 3 below shows a simple example of a CSS rule. There are different kinds of CSS selectors as shown in Figure 2.

It would take a separate article to explain all the features of CSS selectors. You should take some time to refer to other CSS-related reading materials to fully understand the inner workings of CSS. The CSS Zen garden URL shown in Resources is a great place to experience the power of CSS.

Listing 3. A simple CSS rule
body {
   color: maroon;
   font-size: medium;
   text-align: center; 
   background:green; 
}
		


Figure 2. CSS selector types
CSS selectors

Several Ajax frameworks provide abstractions of code libraries for I/O, network, graphics, data, and so on. The Eclipse-based Aptana tool provides nice integration with many such Ajax frameworks in one IDE. However, discussions about such Ajax frameworks are outside the scope of this article. Ajax-related code for the bank scenario is implemented using plain JavaScript, primarily to keep it simple and let you experience some of that code directly in the application rather than through a framework library. After finishing up with this series, you should take a look at Ajax frameworks such as Dojo, Rico, Script.aculo.us, and Prototype.

Ajax keeps the user interface responsive while working with the server for data, resulting in no visual interruptions for the user.

Ajax HTTP interaction

The previous section reviewed some of the XHTML, CSS, and DOM techniques that are part of Ajax. In addition, the way in which HTTP interactions (with the mid-tier server) are done is also central to the nature of Ajax applications. Ajax provides a new way for browser applications to interact with the servers in an asynchronous fashion. It is profoundly different from the classic browser applications in that users do not have to wait and watch the hourglass spin when they click on a Submit button in an HTML form. This asynchronous HTTP communication is supported by XHR, which is a browser object that enables the browser-side JavaScript code to make asynchronous HTTP server requests. It allows you to make HTTP requests, receive responses, and update parts of the page completely in the background, resulting in no visual interruptions for the user. Ajax keeps the user interface responsive while working with the server for data. See Resources for efforts currently underway in W3C to standardize XHR. Figure 3 shows the various object methods and properties of XHR:


Figure 3. XML HTTP Request (XHR) object methods and properties
XHR object methods

Here's a high-level description about the sequence of operations for XHR:

  1. Create an instance of the XMLHttpRequest object.
  2. Use the XMLHttpRequest object to make a call to the server by defining a callback function that is executed automatically when the server response is received.
  3. Deal with the server's response in the callback function.
  4. If needed, go to step 2 for making the next interaction with the server asynchronously.

I'll address specific implementation details about using XHR in this bank scenario later.

Building blocks of the Ajax browser application

Our browser application is made of the following artifacts:

  • XHTML file
  • CSS file
  • XHR JavaScript file
  • Client-side business logic in JavaScript
  • Utility JavaScript files as needed

The XHTML file is the anchor file that users point their browsers to for starting the application. This file mainly contains all the user interface elements that are primarily made using common HTML tags such as <DIV>, <SPAN>, <TABLE>, and <FORM>. This file also uses several other browser technologies to add styling, communications, and data format support.

The CSS file provides the rules for adding required styling to user interface elements. Because CSS is a vast topic, it is not possible to address all the CSS features in this scenario. However, I'll highlight some basic and important CSS features in the context of this application.

The XHR file explains the logic about initializing the XMLHttpRequest object in a browser-agnostic way. It also explains how you can use XHR in an asynchronous communication mode. Instead of reinventing the XHR logic, you'll use a style in which XHR is widely used in the Web development community today.

In the client-side business logic, JavaScript is used to demonstrate Ajax manipulation of the bank scenario screens, an event model that aids in the data-only interactions with the server and asynchronous handling of server responses. For those who are not familiar with Ajax concepts, this module in itself teaches you a few of the central concepts that can be applied in any single-page based Ajax browser application.

In addition, one of the building blocks of this browser application also includes an open source utility for JavaScript Object Notation (JSON) data handling. You'll learn more about that in Part 3 of this article series.

Implementing the Bank portal as an Ajax browser application

Our bank scenario requires a simple browser interface that bank tellers use to perform the core functions you implemented earlier in a PHP module. You will use the Aptana Web IDE to build that. At the time of this writing, Aptana Web IDE provides a simple way to build XHTML, CSS, and JavaScript-based browser applications. Aptana is a free-of-cost plug-in that seamlessly fits in the Eclipse environment along with the PDT tool. It is still under development, but the intermediate version available at this time is adequate for the needs of developing our bank scenario. Even though you will implement the Ajax features in the bank scenario using raw JavaScript, Aptana provides you integration capabilities with several other open source Ajax framework libraries.

Follow these steps to create a single-page Ajax browser application:

  1. In Eclipse, change the perspective to Aptana: Select Window->Open Perspective->Other->Aptana and click OK.
  2. In the Aptana perspective, in the bottom left frame, select the Project tabbed view.
  3. Right-click the BankTeller project and select New->HTML file:
    1. In the File name field, type index.html and click Finish.
  4. Replace the contents of the index.html file by entering or pasting the source code in Listing 4 and click File->Save.
  5. Right-click the BankTeller project and select New->CSS file:
    1. In the File name field, enter BankTeller.css and click Finish.
  6. Replace the contents of the BankTeller.css file by entering or pasting the source code in Listing 5 and click File->Save.
  7. Right-click the BankTeller project and select New->JavaScript file:
    1. In the File name field, enter xhr.js and click Finish.
  8. Replace the contents of this file by entering or pasting the source code in Listing 6 and click File->Save.
  9. Review the comments in these files to understand the code or refer to the next section, which provides a high-level description about the code logic.

So far, you have completed two thirds of the required artifacts for the single-page Ajax browser application! You'll create the remaining parts of the browser application in Part 3 of this series.

Logic in the Bank portal browser application

You have created the XHTML and CSS artifacts along with a utility file related to XHR. The XHTML file (index.html) file is the starting point for this application. This is the only file that the user of the bank teller application can see in the browser's address bar. All other artifacts are pulled from the server into the browser session along with the index.html file. If you look in the <HEAD> section of the index.html file, you can see the following HTML tags:

<script language="JavaScript" type="text/javascript" src="xyz.js"></script>

The script tag defines one or more scripts that can be invoked by elements within the document. In this particular case, it loads the JavaScript code from an external file. This is how you load the bank teller application's JavaScript code from three different JavaScript files:

<link rel="stylesheet" type="text/css" href="xyz.css" media="all" />

The link tag associates style sheet (CSS) rules defined in an external file. This statement links the specified CSS file into the HTML document, thereby affecting the style of the entire Web application.

All the artifacts associated with the presentation content for the bank teller application are downloaded once during startup time. That means it is necessary to segment the individual screens that will be part of the application so that they can be made viewable by the user when needed. This is easily done by including all the user interface controls for a screen inside of a separate <DIV> element. The whole application is inside of a <DIV> element called mainPage. Then there are six other sections in this browser application that are all placed in their own <DIV> element. In turn, all these other six <DIV> sections are enclosed within the mainPage <DIV> element. Having organized these different UI sections this way, it will become easier to control them through DOM manipulation, which Part 3 of this series will explain.

When the application loads, an event handler (initOnPageLoad) is set in the <body> element. This event handler is called at the very beginning so that the initial screen contents can be set to be viewed. Similar to the <DIV> tag, <SPAN> tags also serve the useful purpose of setting up a menu-like structure in the initial screen by just using simple text enclosed within a <SPAN> tag. Notice that these <SPAN> elements have three different mouse action-related event handlers. These event handlers simply use the CSS style rules to highlight and unhighlight the menu items. When one of these menu text items is clicked, then the corresponding onclick event handler makes the corresponding screen appear in the browser window. This is all done not by going to the server, but just by manipulating the browser DOM locally. Another interesting user interface control is the footer section, which is stapled to the bottom of every screen. At any point in time, the screen layout has the mainPage and the pageFooter <DIV> elements. One of the other sections (deposit, debit, portfolio, or bank teller action result) is placed in the middle of these two <DIV> elements -- yet another flexible Ajax design principle.

The CSS file (BankTeller.css) contains the CSS rules that are applied to the user interface elements of this browser application. Several features of CSS are demonstrated through these CSS rules. At a high level, HTML selectors, ID selectors, and class selectors are used widely in this application.

For example, at the top of the CSS file, the body HTML selector redefines the font and background color of the entire browser application page. At the bottom of the CSS file, the portfolioActionButton is used, which is an ID selector. This indicates that all the HTML tags defined in the HTML file (index.html) with that ID string will carry the style defined under #portfolioActionButton CSS rule. Similarly, you can see the use of a class selector in the .tellerOptionsLink CSS rule, which applies to all the HTML tags that are assigned to the tellerOptionsLink class. Also notice the use of group selectors, where two or more selectors are grouped together to have the same style declarations. Examples of group selectors are in many places in the BankTeller.css file. At the bottom portion of the CSS file, you can see that all three action buttons are grouped together (#depositAmountActionButton, #debitAmountActionButton, and #portfolioActionButton) to receive the same button style properties. Another advanced CSS feature called a descendant selector is also demonstrated. A descendant selector lets you style individual descendant elements depending on their parent selector. An example of this is shown in the CSS file to style all the columns in a table, for example, <td> in <table>, by assigning a particular cell padding. Search for table.depositAmountButtonTable td and you will see the application of descendant selectors. You can refer to Figure 2 to quickly check the CSS syntax for HTML, ID, and class selectors.

The XHR file (xhr.js) contains two functions. One is to create a XHR object that can be used to exchange (send and receive) application-specific information with the mid-tier service. The function createRequest prepares an XHR object. At the time of this writing, the XMLHttpRequest is supported in different ways in different browsers. Especially, the two most popular browsers -- Internet Explorer (IE) and Mozilla Firefox -- support XHR differently.

XHR is implemented in different ways in different versions of IE. This function tries to create an XHR object using browser-specific techniques. In a non-IE browser, an XHR object can be created simply by instantiating the built-in XMLHttpRequest class. In IE version 6.0 and above, it is done using the ActiveXObject and XMLHTTP in Msxml2. In all other versions of IE, it is done using the ActiveXObject and a different instance of XMLHTTP. Microsoft is working on providing XHR support similar to other browsers. Until that happens, the logic in this function is required. The other function, sendHttpRequest, is used to send any arbitrary data to the mid-tier service. It interacts with the mid-tier service using a REST-style access mechanism using the POST HTTP verb. This function takes the following four parameters:

  • XHR object
  • Callback function (null if no callback is needed)
  • URL to which data needs to be sent
  • Data (application-specific data to be sent to the mid-tier service)

The sendHttpRequest method sends the data to the mid-tier service using the XHR object. If a callback function is provided, this function sets the onreadystatechange property of the XHR object to that callback function. Then, it opens an HTTP connection to the mid-tier service. It sets any required HTTP headers and then sends the data to the mid-tier service. If a callback function was provided, the send method of the XHR object returns immediately without waiting for a server response. In that case, the server response is handled by the callback function when the server response arrives at the browser. The details about that will be outlined in Part 3. If there was no callback function provided, the send function blocks and waits until the server response arrives, or else it raises HTTP errors.

The single-page browser application code in Listing 4 generates a simple browser interface used by bank tellers in performing bank operations, such as deposit, debit, and calculate portfolio values. The code provides three forms as part of this single-page Web application. Each of those three forms provides a HTML drop-down box that is populated with the account holder names. Then it provides an edit field for the user to enter the amount to deposit or debit. Three action buttons let the bank teller perform the required bank function. Three buttons on this application are designed to access a mid-tier REST service, which you will develop in Part 3. Until you develop that PHP module, these bank teller functions will not be functional. Similarly, you will also develop the JavaScript file (BankTeller.js) in Part 3.

Many new Ajax techniques were used to develop our bank scenario. If you're a novice Web developer, the discussions here introduced you to several new areas. You should analyze the semi-built browser code and the mid-tier code thoroughly to fully understand them. If you're an advanced Web developer, you could attempt to complete the remaining tasks (as listed in the next section) by yourself. And don't worry if you can't complete the pending tasks -- Part 3 of this series will help you do just that.

Conclusion

You have built major portions of the bank scenario so far. Even though you've only gone through part of the end-to-end Ajax application scenario, you learned about the database, the core business logic built into a PHP module, and the Web user interface delivered via Ajax technologies. In the bank scenario diagram from Part 1, notice that you still have to build the following items to complete the entire scenario:

  • A JavaScript module that holds the client-side logic and asynchronous communications logic to do data exchanges with the server.
  • A PHP module that contains the Web service SOAP client code for a remote stock-quote Web service.
  • A PHP module that acts as a REST service to front-end the calls to the business logic in the other PHP modules that are part of this scenario.
  • Integration of all the artifacts to complete the scenario.
  • Deploying and testing the end-to-end Ajax-PHP scenario.
  • Debugging the end-to-end scenario using client-side and server-side debuggers.

Through the materials covered so far in Part 1 and Part 2, you should now have gained insights into the rich capabilities of the open source technologies available on all three tiers, as well as an understanding of specific Eclipse Ajax-PHP development tools. The code artifacts for DB creation of SQL, server-side Bank Logic in PHP, and Bank Portal (XHTML, CSS, and XHR) are provided in the download file included with this article. Stay tuned for the third and final part of this series. Until then, review and familiarize yourself more with some of the core Ajax and PHP concepts and development techniques you applied in the bank scenario so far.



Download

NameSizeDownload method
wa-aj-end2end2.zip14KBHTTP

Information about download methods


Resources

Learn

Get products and technologies

About the author

Photo of Senthil Nathan

Senthil Nathan is a senior software engineer at the IBM T.J. Watson Research Center in Hawthorne, New York. He has 23 years of experience in building software for different kinds of enterprise applications. His current professional interests are fully buzzword-compliant -- including SOA, Web services, Stream programming, Java 2 Platform, Enterprise Edition (J2EE), PHP, Ruby On Rails, Web 2.0, and Ajax development.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Open source, XML
ArticleID=231671
ArticleTitle=End-to-end Ajax application development, Part 2: Implement the Ajax client and server tiers
publish-date=06192007
author1-email=sen@us.ibm.com
author1-email-cc=ruterbo@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers