| By Anil Sharma | Article Rating: |
|
| April 18, 2007 08:00 AM EDT | Reads: |
2,127 |
This content is reprinted from Real-World AJAX: Secrets of the Masters published by SYS-CON Books. To order the entire book now along with companion DVDs for the special pre-order price, click here for more information. Aimed at everyone from enterprise developers to self-taught scripters, Real-World AJAX: Secrets of the Masters is the perfect book for anyone who wants to start developing AJAX applications.
Post Changes to the Servlet
In the MainPage-9.html, we add a new link called "Save" in the top toolbar. It's used to save the changes made by the user using an AJAX request.
Refer to the implementation of the "save" method in the MainPage-9.html. It constructs a request object. It sets the service specification using a "setServiceSpec" method. It also sets the "xmlDoc" of the request to the change list retrieved from the form. The "processRequest" method sends the service specification as one of the parameters of the URL request and "xmlDoc" as the body of the POST request. The "save" method and resulting URL request are shown in Listing 5.22.
Listing 5.22 - Save Changes
// called when the user clicks on the ‘save' button.
function save() {
// retrieve changes as XML from the form
var s = projectSummary.getChangeList();
if (s == null || s == "") {
// there are no new changes
alert("There are no changes available to save");
} else {
// Changes are available
//alert("The following changes are made by the user:\n" + s);
// Construct an AJAX request
var req = new DataRequest(svcURL, saveRequestCompleted,
saveRequestFailed, saveRequestTimedout);
// sets service specification
req.setServiceSpec("ProjectService", "saveChanges");
// sets XML document to be sent as the body of XML
req.xmlDoc = s;
// process the request
ajaxEngine.processRequest(req);
}
}
// called if the save request completes successfully
function saveRequestCompleted(response) {
alert("Save succeeded, the changes recorded in the form will be cleared");
// since the changes have been saved, clear the recorded changes
projectSummary.clearChanges();
}
Let's examine the overall interaction using the following screensshots, URL, and XML documents.
Figure 5.7 shows the change list XML sent by the client in the request's body:
Below is the URL. Notice that the service specification is sent as one of the parameters of the URL. The name of the parameter is "service_spec."
http://localhost:8080/project?service_spec=<service name="ProjectService">
<method name="saveChanges"></method></service>&_=
The following is the service specification document received by the server:
<?xml version="1.0" encoding="UTF-8"?>
<service name="ProjectService"><method name="saveChanges"/></service>
The following is the XML document received by the server in the body of the POST request:
<?xml version="1.0" encoding="UTF-8"?>
<ChangeList>
<Project id="1">
<name>Marketing Campaign(2006)</name>
<startDate>4/3/2006</startDate>
<endDate>12/4/2006</endDate>
<description>Draft - Marketing Campaign Project (2006). </description>
</Project>
</ChangeList>
Notice that the XML documents on the client and the server are consistent. The server can process the XML documents as it wishes. This concludes our end-to-end discussion of an AJAX UI scenario. In the process we demonstrated how to structure AJAX pages (code) and how to make use of the MVC pattern for cohesive working of these pages.
Client-Side Renderer
We discussed the View implementation using an HTML template. This is a key reason that AJAX is such a compelling rich client technology. As the next step, it might be desirable to parameterize the templates so they can be applied repeatedly. This can be done in an AJAX UI, albeit differently. Once a pattern is standardized as an HTML template, JavaScript code can be used to render it in the client space based on a set of parameters.
Let's see this using an example that renders a form on the client side. The ProjectSummary.html is a form template. The HTML fragment that renders the form is shown below. It uses an HTML table element with two columns for the form. The first column displays the labels and the second column displays the fields.
<table id="projectSummaryElement" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<!—first label -->
<td class="formLabelCell">Project Name:</td>
<!—first field -->
<td class="formFieldCell">
<input type="text" id="name" class="FormField" style="width:400px" >
</td>
</tr>
<tr>
<!—second label -->
<td class="formLabelCell">Start Date:</td>
<!—second field -->
<td class="formFieldCell">
<input type="text" id="startDate" class="FormField"
style="width:150px" />
</td>
</tr>
... ... ... another row
... ... ... one more row
</tbody>
</table>
We provide an additional method called "render" in our Form class to render the form based on the list of its components. The "render" method of the Form is shown in Listing 5.23.
Listing 5.23 - ‘Render' Method of Form
// renders Form's element on the client side
Form.prototype.render = function() {
// table is the top level element of the Form.
var table = document.createElement("table");
table.border = "0";
table.cellspacing = "0";
table.cellpadding = "0";
table.width = "100%";
table.id = this.name;
var tbody = document.createElement("tbody");
table.appendChild(tbody);
// For each field component create a row
for (var i=0; i<this.components.length; i++) {
var tr = document.createElement("tr");
tbody.appendChild(tr);
var comp = this.components[i];
// if the component is not a TextAreaComp
// add label using the display name of the comp.
if (comp.type != "TextAreaComp") {
// create cell for the label
var td = document.createElement("td");
td.style.width = "100px";
// specify the css class name for the label cell
td.className = "formLabelCell";
td.appendChild(document.createTextNode(comp.displayName));
tr.appendChild(td);
}
// create cell for the field
td = document.createElement("td");
td.className = "formFieldCell";
// render the component by calling its ‘render'
var elem = comp.render();
if (comp.type == "TextAreaComp") {
// text area spans across two columns
elem.style.width="100%";
td.colSpan = "2";
} else {
elem.style.width="200px";
}
elem.className = "FormField";
// add the component's element to the cell
td.appendChild(elem);
// add the field cell to the row
tr.appendChild(td);
}
this.element = table;
}
The following code shows the render method of one of the components (SelectComp). Refer to the source code for the implementation of the "render" method for other components.
Listing 5.24 - ‘Render' Method of SelectComp
SelectComp.prototype.render = function() {
var elem;
// create select element
elem = document.createElement(‘select');
// for each option, add option element
if (this.options) {
for (var i=0; i<this.options.length; i++) {
var option = this.options[i];
// create option element
var oe = document.createElement("option");
// set the value of the option element
oe.value=option.value;
// set the label of the option element
oe.label = option.label;
oe.appendChild(document.createTextNode(option.label));
elem.appendChild(oe);
}
}
this.element = elem;
return elem;
}
Based on the changes above, we can render our project summary form using JavaScript code without the HTML template. Refer to the ClientSideRenderer.html to see how a client-side renderer is used. The code that renders the form on the client side is shown in Listing 5.25.
Listing 5.25 - Client-Side Rendering of a Form
function initialize() {
// create a Form component
var projectSummary = new Form("projectSummaryForm");
// set the field components of the form
// specify the display name for each component
projectSummary.setFieldComp(new TextComp("name", "Project Name:"));
projectSummary.setFieldComp(new DateComp("startDate", "Start Date:"));
projectSummary.setFieldComp(new DateComp("endDate", "End Date:"));
// set a select component
var sc = new SelectComp("status", "Status:");
// set options for the select field
sc.addOption("Green", "Green");
sc.addOption("Yellow", "Yellow");
sc.addOption("Red", "Red");
sc.addOption("Not Started", "Not Started");
projectSummary.setFieldComp(sc);
projectSummary.setFieldComp(new TextComp("resource", "Resource:"));
// add a text area field
projectSummary.setFieldComp(new TextAreaComp("description", "Description:"));
// now render the form
projectSummary.render();
// attch the rendered element of the form to MainArea
attachElement("MainArea", projectSummary.element);
}
The resulting view using the client-side rendering is shown below.
Conclusion
HTML, CSS, JavaScript, and XML messages for information exchange provide a solid foundation for building a rich client user interface. Organizing and layering the views, models and controllers of the UI using the MVC pattern produces a reusable framework. It also facilitates independent development of views by a UI designer. Developers can work independently on models and controllers (application behavior). In the initial stages XML files can be used as the data source. This helps in firming up the data model and message formats. On the other hand, the server team can test the
interaction with the UI using a browser. Such modular development and ease of integration are definitely going to boost the team's productivity.
Figure 5.8 summarizes the layering of the AJAX applications components discussed in this chapter.
Additional Information
Additional resources that you might refer to are listed below.
- www.w3schools.com/default.asp provides a set of tutorials for HTML, CSS, XML, and JavaScript.
- www.json.org/ provides an introduction to JavaScript Object Notation and a reference to the JSON implementations in different programming languages. JSON can be used in place of XML for information exchange.
- Documentation of Prototype.js is available at www.sergiopereira.com/articles/prototype. js.html
- http://ajaxpatterns.org/ is a good resource for AJAX-related product and discussions.
This chapter was inspired by Professor Niklaus Wirth's classic paper, "Program Development by Stepwise Refinement." My sincere gratitude to Professor Wirth for writing such a wonderful paper. My thanks are also due to the editor of this book Dion Hinchcliffe for the opportunity he created. And I would like to thank Dr. Ashish Tiwari, computer scientist at SRI, Palo Alto, CA, for his gracious help in reviewing the draft of this chapter and providing invaluable comments. My thanks are also due to my sons Abhineet and Praneet for being a sounding board for the content's clarity and keeping the environment around me cheerful and entertaining. Last, but not least, I would like to thank my lovely wife Rajshree for her patience and rock-solid support in all my endeavors. Finally, I dedicate this work to my loving mother Sita Sharma who is not with us anymore but her soul continues to guide me.
This content is reprinted from Real-World AJAX: Secrets of the Masters published by SYS-CON Books. To order the entire book now along with companion DVDs, click here to order.
Published April 18, 2007 Reads 2,127
Copyright © 2007 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Anil Sharma
Anil Sharma is a founder of Vertex Logic and architect of its AjaxFace product. He is working with Vertex Logic's customers and helping them deploy WEB 2.0 applications built using AjaxFace. These applications are in the areas of online printing, community WEB sites and social networking. He is driving future products of Vertex Logic. Prior to Vertex Logic, he was CTO and founder of Softrock Systems and Component Plus. There he built a model driven application platform using J2EE. His primary interests include user interface infrastructures and model driven applications. He is one of the contributors of the book "Real World AJAX - Secrets of the Master".
- Cloud Computing on Gartner's Top 10 List and SYS-CON Events' 2010 Calendar
- Confessions of a Ulitzer Addict
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Moving Your RIA Apps into the Cloud: Seven Challenges
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Windows 7 – Microsoft’s First Step to the Cloud
- Ulitzer Provides a Powerful Social Journalism Platform
- Jill Tummler Singer, Deputy CIO of CIA, Keynotes at GovIT Expo
- Open Source Mobile Cloud Sync and Push Email
- Practical Approaches for Optimizing Website Performance
- The Difference Between Web Hosting and Cloud Computing
- Cloud Computing on Gartner's Top 10 List and SYS-CON Events' 2010 Calendar
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Confessions of a Ulitzer Addict
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- US Post Office Hops a Ride on NetSuite’s Cloud
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- WPF Controls by DevExpress
- Moving Your RIA Apps into the Cloud: Seven Challenges
- Building a Drag-and-Drop Shopping Cart with AJAX
- What Is AJAX?
- Google Maps! AJAX-Style Web Development Using ASP.NET
- Flashback to January 2006: Exclusive SYS-CON.TV Interviews on "OpenAjax Alliance" Announcement
- AJAXWorld Conference & Expo to Take Place October 2-4, 2006, at the Santa Clara Convention Center, California
- AJAX Sponsor Webcasts Are Now Available at AJAXWorld Website
- How and Why AJAX, Not Java, Became the Favored Technology for Rich Internet Applications
- "Real-World AJAX" One-Day Seminar Arrives in Silicon Valley
- AJAXWorld University Announces AJAX Developer Bootcamp
- AJAX Support In JadeLiquid WebRenderer v3.1
- Where Are RIA Technologies Headed in 2008?
- Struts Validations Framework Using AJAX




































