Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Putting a YUI Face on a Java Web Application : Page 2

Learn how to use Yahoo User Interface (YUI) Web components to develop a real world application with just the right mix of JavaScript/AJAX.


advertisement

Design: Striking a JavaScript/HTML Balance

Developing a rich user interface (RUI) with JavaScript poses the challenge of determining how much HTML and how much JavaScript to use. Using JavaScript and AJAX for everything (starting from loading the UI elements) and no HTML would impose too many requests on the server. A better strategy would be to keep a HTML page for every feature or module and back the page with JavaScript for the RUI behavior such as animation, drag and drop, sending server requests, and handling the events from the UI elements. This is the strategy the application in this article will employ.

Layout

The screen area for the application is divided into the following four parts (see Figure 1) to achieve the desired functionality:
  • Action Area: This container holds the buttons ("Bank, " "Web, " "Birthdays," and "Appointments") for the user to choose which entry to manage.
  • Listing: This container holds the list of entries for Bank, Web, etc., depending upon the context selected.
  • Work area: This container occupies the majority of the page. It displays the complete details of the selected entry on the listing panel.
  • Console: This container displays status messages.

To get the desired layout, the HTML markup needs to be defined first. The file /index.html in the source code download for the application does that as follows:



<body class="yui-skin-sam"> <div id="actionDiv"> </div> <div id="optionsDiv"> </div> <div id="workspaceDiv"> </div> <div id="consoleDiv"> </div> </body>

The style class of the body should be set to yui-skin-sam, a default skin class provided for YUI. YUI components need this class to work properly; you can customize it to suit the needs of the application. For example, the following definition from the file /css/main.css in the demo application sets the background color of the container rendered by YUI to white:

.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd { background-color: #FFFFFF; }

The YUI Layout component is initialized to hook up to the markup defined (see Listing 1 for an example, the JavaScript class YAHOO.widget.Layout in the demo application). A number of things in the class defined in Listing 1 are worth noting:

  • The YAHOO.widget.Layout class is initialized and rendered. The position attribute is passed with a constant to indicate where to position the container. The body attribute refers to the ID of the div defined in the HTML markup.
  • A namespace, devx.yuiapp, is created and the JavaScript class Main is declared. The Main class holds references to all other JavaScript classes created and acts as the entry point class for the index.html page.
  • In the Main class constructor, the init method is registered with onDOMReady for callback. When the index.html page content becomes available, init is called. All the initialization pertaining to the index.html page, such as initializing the buttons, loading data for the current context, and so on, is done in init.
  • Within the init method, various places make references to the Main class using the this keyword. However, the init method is called in a different scope because it is a callback method. To let this refer to the Main class in the callback, the reference of the Main class is passed in the second argument and true is passed in the third argument to onDOMReady.
  • An instance of LogReader is created. This attaches a panel to the page for displaying log messages. A call to YAHOO.log would result in messages printed in this panel.
  • The instance of the Main class is created and assigned to a global variable main.

Click here for more detailed notes and examples for the YUI Layout class, but always employ the following best practices for defining a layout:

  • Use relative positioning (which refers to the CSS attribute position) when adding components or containers from top to bottom, and use absolute positioning if laying out components or containers left to right in the page. Absolute positioning requires you to define the attributes left and top.
  • Load all the page elements during initial load. This makes adding listeners to the UI elements easy. Otherwise, you need to hack around to attach listeners.
  • Link the CSS files Reset, Base, Grids, and Fonts (all part of YUI) in the page to set default style definitions for all the HTML tags. This ensures a consistent look and feel for your application across browsers.

Action Area

To add buttons to the action area panel, you need to define HTML markup and then you should hook up the YUI widget class Button instance. The files /index.html and /js/action_bar.js in the demo application do that as follows:

/index.html <div id="actionDiv"> <input type="button" id="banksBtn" name="banksBtn" value="Banks"> <input type="button" id="webBtn" name="webBtn" value="Web"> <input type="button" id="birthdaysBtn" name="birthdaysBtn" value="Birthdays"> <input type="button" id="appointmentsBtn" name="appointmentsBtn" value="Appointments"> </div> /js/action_bar.js var hideAllListings = function () { main.banksListing.hide(); main.webListing.hide(); var bdaysListDiv = YAHOO.util.Dom.get('bdaysListDiv'); bdaysListDiv.style.visibility = "hidden"; var apptsListDiv = YAHOO.util.Dom.get('apptsListDiv'); apptsListDiv.style.visibility = "hidden"; }

The demo application uses the YUI DOM class to get the reference of a div definition for hiding out-of-context listings.

var onBankButtonClick = function () { hideAllListings(); hideAllDetails(); // Show banks listing & details main.banksListing.show(); main.bankDetails.show(); } this.banksBtn = new YAHOO.widget.Button("banksBtn"); this.banksBtn.on("click", onBankButtonClick, null, this);

The ID of the button input element is passed in the constructor, and the callback method onBankButtonClick is added to listen for click events. Note that when calling the registered method using the scope of the ActionBar class instance, you need the third argument to the on method.

When the user clicks the Bank button, all other listings and details are hidden and the panels pertaining to Bank appear. References to other classes are obtained via the global variable main.

Bank and Web Listing

The demo application in this article uses mock data (retrieving data from the server is saved for the next article in this series). The class BankListing displays the list of persisted banks and listens for events when an entry is selected. Here's an example from the file /js/bank_listing.js in the demo application:

devx.yuiapp.BanksListing = function() { // Constructor } devx.yuiapp.BanksListing.prototype.init = function () { // Test data. This will be fetched from the database var bankData = { banks: [ .... ] }; .... this.list = new devx.yuiapp.List('Bank', bankData.banks, 'banksListDataTableDiv', onBankSelection); this.list.init(); }

Because listing entries are common for any entity (Bank, Web, etc.), a common class devx.yuiapp.List is defined. This reusable class is instantiated for every entity type. Listing 2 provides an example, the /js/listing.js file in the demo application. YUI DataTable is used to represent a listing. Here are some other key points from Listing 2:

  • The column definition, data source definition, and container to render the table to are passed to the DataTable constructor.
  • Listeners are added to the table for highlighting or not highlighting rows when the user hovers the mouse over the table.
  • A custom formatter is written to display an image for a row instead of the URL.
  • The callback method _rowSelectEvent is registered to be invoked when the user selects an entry in the listing. This call will be delegated to the BankListing or WebListing class to open up the details pertaining to that record.

Bank and Web Details

When the user selects an entry, the listing should load details pertaining to that selection. The following code from the /js/bank_listing.js in the demo application accomplishes this for a Bank selection:

var onBankSelection = function (id) { main.bankDetails.load(id); }

When the user makes a selection in the Bank listing, the method onRowSelection will be called back from the Listing class. The class BankDetails abstracts the data and behavior related to displaying and allowing modifications to attributes such as Bank accounts, credit card details, etc. Listing 3 shows an example, the /js/bank_details.js file from the demo application. The load method is invoked when the user selects an entry in the listing. YUI's Element class is used to hook up to the input text fields for setting and getting values. The onblur event is registered to validate the input.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap