Wrox Home  
Search
Professional Joomla!
by Dan Rahmel
October 2007, Paperback


Excerpt from Professional Joomla!

Adding Ajax to Joomla! Web Applications

by Dan Rahmel

Ajax (which stands for Asynchronous JavaScript and XML) combines a powerful set of technologies for Web 2.0 sites. Using Ajax technology, you can make the user experience far more interactive than previous Web site implementations. In the past, changes to parameters or the selection of buttons on a Web page required the changes be sent back to the Web server for an update. The browser would have to wait for the entire modified page to be returned to display the revisions. Using that process, user interaction with a Web application was fairly clunky.

In a Web application designed with Ajax, near-immediate interaction is possible. User-interface requests such as changing the sort order of a table by clicking on the column headings can be handled on the client with little delay. If the interaction involves requesting additional information (such as help text on a line item), rather than requesting an update of the entire page, Ajax technology allows small amounts of data to be exchanged with the server. Updates can happen dynamically, so the entire Web page doesn't need to be reloaded.

Joomla has incorporated functionality that promotes Ajax technology. A Joomla site can support Ajax background information exchange for a more dynamic and responsive user experience.

For more Ajax background, please read What is Ajax? by Chris Ullman.

A Simple Joomla! Ajax Component

An Ajax system can become complicated very quickly. There are many pieces to the puzzle, so it is easy to get lost at the beginning. Therefore, a beginning demonstration of rudimentary Ajax technology will be useful. This example will essentially provide a "Hello World" style Ajax pop-up to illuminate how the various pieces of the puzzle fit together.

The demonstration will consist of a single Web page that has a bordered paragraph with the text "My Product." When the mouse cursor passes over the paragraph, JavaScript executes a query to a Joomla server for a component. That returns a simple message regarding the inventory status of the product. The received message is displayed in an alert box, as shown in Figure 1.

This primitive example supplies a skeleton of a Joomla Ajax solution that you'll soon extend to provide a more substantial Ajax solution. However, it will include all of the most important pieces that will mirror the structure of advanced Ajax applications.

Figure 1
Figure 1: The message displayed in the alert box has been dynamically requested and received from a Joomla component.

Creating the Component

The first piece in the application is the Joomla component. A Joomla component can be directly queried so that it will provide output without any menus or the other user-interface items that usually surround it. Therefore, the component only must output a single line of text that the Ajax application will display.

Begin by creating a folder \com_productinfo on your local drive. Inside the folder, create a file productinfo.php and enter the following code:

<?php
// no direct access
defined( _JEXEC' ) or die( Restricted access' );
echo That product is in stock!';
?>

You will need a XML descriptor file to allow Joomla to install the component. Create a file called productinfo.xml and enter the following code:

<?xml version="1.0" encoding="utf-8"?>
<install version="1.5.0" type="component">
     <name>ProductInfo</name>
     <version>1.5.0</version>
    <description>Product Info component for Ajax queries</description>
    <files>
          <filename component="com_productinfo">productinfo.php</filename> 
    </files>
</install>

Archive the folder containing the two files as com_productinfo.zip and use the Extension Manager to install it into the Joomla system. You can test the component by performing a direct URL query by typing the following address into your browser:

http://localhost/index.php?option=com_productinfo&format=raw

If the component is working properly, you will see the single line of text output by the component in the browser window, as shown in Figure 2. If you view the source of the window, the HTML code will show nothing except the exact text. By setting the format to raw (the second query parameter), Joomla executes the specified component and returns only the output that it has generated. This method is exactly how the Ajax Web page requests information for display.

Figure 2
Figure 2: The component will display the product's stocking status in plain text.

Creating the Ajax Web Page

The Ajax Web page will call upon the component for the product information and then display this information in an alert window. This file will be more complicated because it includes three steps of the Ajax process: user interaction, information request, and information receive/display.

The user interaction consists of a simple onMouseOver event that will be constructed to execute a JavaScript function. In this case, the event will be set up to activate when the user places the mouse cursor within the area specified by a paragraph or <p> tag.

The information request involves executing the displayAjax() function and passing it the URL that will provide the requested information. This function will open an XML request object (data is primarily exchanged using XML) and send a request to the URL that was passed to it.

The displayAjax function first creates an XML request object. As with most browser code, the execution must detect the browser where it is being executed, and then use logic specific for that one. The IE browser both pioneered the XML request interface (through an ActiveX object) and then violated the standard by not implementing the common interface. While this has been resolved in the later versions of IE (post IE-6), the code must take into account the large number of older IE browsers in use.

Once created, the code sets the XML request object's event return function to handle the results, opens the connection, and sends the request. When it sends that request, it will pass a function pointer to indicate the routine to execute when the request is complete. Remember that the first A in Ajax stands for asynchronous, so the rest of the Web page can continue functioning without waiting for the request to be answered.

When the displayReturn() function is activated, it first checks the returned information. The request might have timed-out or been given some other error. The function makes sure there is a valid message, and then displays the message in an alert box.

To see Ajax in action, enter the following code into a text editor, save it as AjaxRequestTest.html, and open it in your browser:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" language="javascript">
// Create XML request variable
var myRequest = false;
function displayAjax(myURL) {
     // Clear myRequest
     myRequest = false;
     // For browsers: Safari, Firefox, etc. use one XML model
     if (window.XMLHttpRequest) {
          myRequest = new XMLHttpRequest();
          if (myRequest.overrideMimeType) {
               myRequest.overrideMimeType(text/xml');
          }
     } else if (window.ActiveXObject) {
          // For browsers: IE, version 6 and before, use another model
          try {
               myRequest = new
                    ActiveXObject("Msxml2.XMLHTTP");
          } catch (e) {
               try {
                    myRequest = new
                         ActiveXObject("Microsoft.XMLHTTP");
               } catch (e) {}
          }
     }
     // Make sure the request object is valid
     if (!myRequest) {
          alert(Error: Cannot create XMLHTTP object');
          return false;
     }
     
     // Link to display function activated when result returned
     myRequest.onreadystatechange = displayReturn;
     // Open the URL request
     myRequest.open(GET', myURL, true);
     // Send request
     myRequest.send(null);
}
function displayReturn() {
     // Check to make sure result came through, 4=complete
     if (myRequest.readyState == 4) {
          // Check HTTP status code
          if (myRequest.status == 200) {
               // Display the responseText
                        alert(myRequest.responseText);
          } else {
               alert(There was a problem with the request.');
          }
     }
}
</script>
</head>
<body>
<p style="border:1px solid black;"
     onmouseover=
     "displayAjax(http://localhost/index.php?option=com_productinfo&format=raw')">
     My Product
        </p>
    </body>
</html>

Place this file at the root directory of your Joomla server to execute it. Note that the URL in the displayAjax() function code currently points to the server activated on localhost. Change the URL to your site URL if you are running the file on a remote server. . When you move the mouse cursor over the paragraph, the message will be displayed in an alert. That wasn't so bad, was it?

With Firefox, the cross-site scripting attack protection will prevent the code from executing on a local drive. When you try to access the page, you will receive an error such as, "Error: uncaught exception: Permission denied to call method XMLHttpRequest.open" and the browser will refuse to display the page. Simply transfer the file to your Web server and access it there to have Firefox display it.

With a basic implementation complete, you could now create a more powerful example. Most real-world Ajax solutions require a combination of dynamic content generation and Ajax interactive technology to allow more information to be retrieved from the same system. Chapter 7 "Joomla! and Ajax" of the book, Professional Joomla! (Wrox, 2007, ISBN: 978-0-470-13394-1), takes this next step by creating a Server-Query Ajax Joomla! component.

Ajax Disadvantages

Given the exciting nature of the Ajax technology, it is easy for developers to overlook the shortcomings. Aside from the complexity that Ajax can add to a Web development project, there are a number of very real problems that will be encountered as Ajax use grows:

  • Ajax Search Engine Optimized (SEO) invisibility
  • Information harvesting
  • Possible security risks

Ajax SEO Invisibility

Since Ajax has begun to spread like wildfire, entire sites are using Ajax for everything from menu display to core information presentation. While it is easy to get caught up in the excitement of a new technology, it is important to recognize where that technology can be best applied. So far, the best uses have been for dynamic user-interface widgets for everything from Netflix to Google Maps.

However, all of the content that is displayed by the Ajax widgets is invisible to search engines. A search engine spider will not execute the code contained in an Ajax JavaScript link. Therefore, while the pop-up content may appear slick and inviting to your users, a search engine will be blind to it.

Make certain that any content you use for Ajax is also present somewhere else on the site using traditional HTML. Using this method, your site will not look empty to the search engine spider. Further, to make sure your site is SEO, be sure to have your central site content in HTML prominent on the central pages. If the content is presented by Ajax and simply included in a low-ranked part of the site for completeness, your search engine ranking will suffer.

Information Harvesting

Most Ajax requests are directly querying for formatted data that is returned to the browser. You have to be careful to prevent unauthorized access and also shield yourself against potential hackers. Most Ajax applications will make a request to your system that you supply with formatted data from within your data stores. This information may be important price/stocking records, or even proprietary company data. With the data returned in XML format, it would take little time or effort for your competitors to author an information harvesting program that simply makes request after request to your Ajax component until all the information it can provide is stored safely in a rogue database.

There are a few ways to guard against this type of information harvesting, but the easiest is to ensure that the requests are not sent with a simple sequential ID number. If you have products numbered 1 through 50, use some other method of ID request so that a harvesting application can't simply loop through the sequence to gain the requested information.

Security Risks

The other danger lies in the potential for a SQL injection attack. In an injection attack, the hacker simply tacks on a full SQL query to the request string. If the receiving program simply passes the parameter received from the request directly to the database, a great deal of private information can be exposed.

Fortunately, Joomla has built-in routines such as getVar() to prevent most of the potentially harmful code from getting through. Be sure to think twice before you decide to circumvent the Joomla security routines because they offer a great deal of tried-and-tested security technology.

This article is excerpted from Chapter 7, "Joomla! and Ajax," of the book, Professional Joomla! (Wrox, 2007, ISBN: 978-0-470-13394-1,) by Dan Rahmel. Dan is an author best known for his work with database systems, PHP, and Visual Basic. He has more than a dozen years of experience designing and implementing information systems and client-server solutions using MySQL, Microsoft SQL Server, Microsoft Access, and Visual FoxPro. He began work as a writer for various magazines, including DBMS, American Programmer, and Internet Advisor. He is the author of more than a dozen books, and his writing has been translated into numerous languages, including Chinese, Japanese, Spanish, French, and Portuguese. In 2006, Focal Press issued a special edition of Nuts and Bolts Filmmaking: Practical Techniques for the Guerilla Filmmaker (Focal Press, 2004) for release in India.