User interfaces based on HTML and hosted in browsers have become quite nearly ubiquitous over the last several years. Thanks to IBM's Open Access API, IBM i RPG applications are able to access an HTML-driven user interface very effectively. ASNA Wings, for example, builds a browser-based user interface derived from existing display file DDS specifications.
When an RPG program has an HTML/browser-based user interface, users can access your application not just from desktop browsers, but also from smartphones and tablets. The pairing of Web-based user interfaces with IBM i RPG applications is a great match because it not only allows the customization and enhancement of cosmetics, but also allows for additional function to be added to the RPG at the presentation level. This means additional power can be added to the RPG without changing any of the logic in the RPG program. For example, you can add features like the ability to call business partner Web services or export Excel data from the new UI very effectively without needing to modify any logic in the RPG program.
All Gain, No Pain!
The ASNA Wings presentation layer is powered by a Microsoft ASP.NET Web site. This "Web site," which is more of an application really than a traditional Web site, is where this type of customization is performed. This article isn't really an introduction to ASNA Wings or IBM's Open Access. Both Wings and Open Access are explained at our Web site. Rather, this article focuses on how you can add more power to the standard Wings UI with just a minor bit of effort.
According to some, the conventional wisdom is that because ASNA Wings uses Microsoft ASP.NET, you have to be a .NET wizard with tons of .NET, JavaScript, and HTML programming skills to customize or enhance the Wings presentation layer. We don't see it that way. From our point of view, if you are a programming wizard in the programming disciplines just described, then the sky is the limit with ASNA Wings. However, if you aren't that programming wizard, ASNA provides powerful helpers that let you plug in lots of power with very little skill required. Unlike competing products, Wings doesn't limit you to a fixed pallet of enhancements. Rather, Wings offers an unlimited pallet of possibilities for programmers of all skill levels. This product review digs into the details of how you can easily add a responsive UI to your Web apps and RPG applications.
The Power of AJAX
Figure 1A below shows the traditional dataflow for a Web app. By default, a Web app functions a little like a green-screen app—that is, it pushes a full screen of data at the browser (with an HTTP response) and the user fills in fields and returns the data to the server (with an HTTP request). Like an old RPG program, with a traditional HTML-based app, data is returned to the back end a page (or a "screen") at a time.
Figure 1A: In a traditional full-page request/response, all of the data on the page is transmitted.
The traditional full block mode is fine for the initial load of the screen, but it doesn't provide the programmer with fine-grained control over dynamically reading or writing data for a specific part of the page. Consider the need to collect a postal code from a user. That postal code can't be validated until all of the data on the page is sent back to the server. AJAX provides a way to defeat this limitation. AJAX isn't a technology; it's a technique for using JavaScript (the computer language that resides in every browser) to send chunks of data to and receive data from the server very quickly. Figure 1B below shows the much slimmer, focused workflow AJAX provides.
Figure 1B: In a granular AJAX request and response, small chunks of data on the page are transmitted very quickly.
One benefit of using AJAX is that it allows a reactive programming model, much like that offered by Windows programming (which is the polar opposite of the block mode model where virtually every mouse or cursor movement can invoke an action). Consider the challenge of validating a postal code. Using AJAX, a call could be made to the server when the postal code loses focus to validate that field. The value is sent with AJAX and an error/ok status is received. This type of call happens in a matter of milliseconds, providing the user with instantaneous feedback.
Recall that AJAX isn't a technology; it's a technique. Therefore, there are many ways to use AJAX in a Web app. A downside of AJAX, especially to the uninitiated, is that its techniques can be very challenging to master. Using conventional techniques, AJAX requires a solid knowledge of JavaScript, CSS, and HTML. It's the rare RPG programmer who's gifted with these skills. ASNA offers a bridge to RPG programmers who want to use AJAX techniques but don't have time to learn all the traditional AJAX gobbledygook.
Next, we'll take a look at how easy ASNA makes harnessing AJAX. The techniques discussed here work in any Wings-modernized RPG application or with a more traditional ASP.NET Web application built with ASNA Visual RPG or an ASNA Monarch migrated app.
A Simple AJAX Lookup
In this section, we'll add a simple AJAX look to a Web page. For this specific example, the lookup is being added to an ASNA Wings Web page. The screen below in Figure 2A shows the original RPG green-screen display.
Figure 2A: Here's the original RPG green-screen display.
Out of the box, ASNA Wings provides the display shown below in Figure 2B. This display uses a standard template that provides a place for your corporate colors and images (which is shown in blue with ASNA images). The vertical menu bar on the left is generated dynamically for each Wings screen, based on the function keys enabled for the screen. The original function keys are also always available for every Wings screen (i.e., you don't have to use a mouse to click an option; you can simply press a function key).
Figure 2B: This is the Wings default rendering of Figure 2A's original green-screen.
Because some users may prefer to eliminate the visual noise of the vertical menu, they can hide it by clicking its "hamburger" icon, which is the little icon with three horizontal bars under the "A" in "ASNA." The screen with its menu hidden is shown below in Figure 2C.
Figure 2C: In this Wings default rendering of Figure 2A, the vertical menu is toggled off.
Zeroing in on the data-entry part of the screen (see Figure 3 below), you'll notice that there is a Status field. This field accepts one of several possible characters to indicate the customer's status. In the original app, this value was selected from a file with an F4 windows prompt screen. Wings migrates those old F4 prompt screens, but, as in the old days, they are little clunky. This is a great place to add an AJAX lookup.
Figure 3: These are the data entry parts of Figures 2B and 2C.
There are many ways to do an AJAX lookup. The popular JavaScript library jQuery and its sidekick, jQueryUI, provide great components to do this. However, as alluded to earlier, there is normally a learning curve to being productive with these tools. However, you'll see that ASNA has abstracted away the need for the learning curve to make it easy for you to extend your Web application user interfaces.
In the case of the customer status lookup, the result we're after is shown below in Figure 4.
Figure 4: An AJAX lookup for the customer Status field is shown.
When the user tabs into the Status field, the dropdown is displayed, allowing the selection of a status. Tabbing out of the list selects the value. This list is populated dynamically upon request. As the file that is providing valid codes is updated, this dropdown always offers the most current values available. This list can be completely driven by the keyboard for heads-down data entry users, or it can be driven by the mouse for the clicking crowd.
Component Installer
Perhaps even more troublesome than needing to learn JavaScript, simply installing the necessary JavaScript and HTML in the correct places in your project for jQuery and jQueryUI can drive you nuts. To negate these issues, ASNA uses a combination of conventions (which generally means what files go in what folders) and a small ASNA Windows utility called the "ComponentInstaller."
Most of the code used in this article was created for a recent ASNA developer conference, ASNApalooza. All of it is available at ASNApalooza's GitHub site. You don't need a GitHub account nor do you need Git installed to use code from GitHub. Simply download the zip files list for the code you're interested in.
The ASNA ComponentInstaller is a Windows command-line app. After opening a DOS command line over the root folder of your ASP.NET Web project, you issue this command line:
Componentinstaller asna-helpers.aspnet
And all of the necessary JavaScript and CSS files are installed in your project for you. Also installed is a dynamic query component with an HTTP interface. This HTTP interface isn't formally RESTful, but at least in spirit it is. It is what AJAX calls to get lookup lists. (If you're curious, the ComponentInstaller is pulling down the components from various projects at the ASNApalooza GitHub site). Having installed these components, you'll only need to write about 12 lines of simple JavaScript declarations to configure a single lookup.
The original application used a data file (named Lists) to store the valid codes for the customer Status field. This file has three fields in it: ListName, Text, and Value. The ListName field defines the values for a given list, and this file contains data for many lists. The values for the Status list are shown below in Figure 5. We'll use this same file for the AJAX lookup.
ListName |
Text |
Value |
Status |
Active |
A |
Status |
Closed |
C |
Status |
Over limit |
O |
Status |
Refer |
R |
Status |
Suspended |
S |
Figure 5: The list values for the customer Status from the Lists file is shown.
And Now the Code!
With formalities out of the way, let's look at the JavaScript required to hook up the customer Status lookup. It is shown below. You'll notice that except for the "if" test to ensure the code is registered for the correct display format, all of the code is declarative. This code is declaring what file is being used for the lookup (the File property) and several other necessary runtime values. Several of the values below are used consistently across all AJAX lookups (i.e., you can copy and paste most of this code for other lists), and some are specific to the given lookup. You can read more detail about each of the values below here.
// ----------------------------------------------------------------------
// Customer status Ajax lookup.
// ----------------------------------------------------------------------
function registerStatusStateLookUp() {
var StatusStateLookUp = new ASNAHelpers.QueryInputArgs();
StatusStateLookUp.url = "../services/jsonservice.ashx";
StatusStateLookUp.Library = "examples";
StatusStateLookUp.File = "lists";
StatusStateLookUp.FieldsList = "ListName,Text:label,Value:value";
StatusStateLookUp.Rows = -1;
StatusStateLookUp.Query = "ListName = '{ListName}' AND Text >= '{Text}'";
StatusStateLookUp.addQueryParm("Text");
StatusStateLookUp.addQueryParm("ListName", "Status");
StatusStateLookUp.addOption("labelTargetId", ->
ASNAHelpers.dspfInfo.field("CUSTREC","SFSTATUS").attr("id"));
StatusStateLookUp.addOption("labelValueId", ->
ASNAHelpers.dspfInfo.field("CUSTREC","SFSTATUS").attr("id"));
StatusStateLookUp.addOption("showLabelOnScroll", false);
ASNAHelpers.autoComplete.registerQuery(StatusStateLookUp);
}
if (ASNAHelpers.dspfInfo.hasFormat("CUSTREC")) {
registerCityStateLookUp();
registerStatusStateLookUp();
}
The code above is substantially more direct, and there is less of it than if you try to roll your own jQueryUI AutoComplete. A detractor could say, "Yes, but you still have to write JavaScript!" And that's true. But you don't have to write much, and you don't have to know much about JavaScript to make it work. And when added to a Web page, users love this kind of user interface enhancement.
Revisiting the Postal Code Challenge
The postal code lookup is a very classic example of how AJAX helps streamline a Web user interface (although this example uses U.S. data, its concepts are applicable anywhere). Most apps that need a user to enter a city, a state, and a postal code have the user enter each of these data items separately. This is probably not the best way to do this because you should be able to derive the associated city and state from the postal code. Ideally, what we'd like is to have the user enter a postal code and then, from the value, be able to select a city and state.
Figure 6 below shows the desired result with a postal code lookup. In this case, direct input for the city and state is not allowed (in fact, the cursor doesn't even stop in these fields as the user tabs through the fields on the screen).
Figure 6: This example shows an AJAX lookup for the customer Postal Code field.
The user can type as many digits of the postal code as is known and then incrementally add other digits. The list dynamically changes to keep up with that change. On a small IBM i Power 720 Express, the lists display so quickly you don't even get the chance to see the status of "busy" as the list is populated and displayed. When the dropdown list is displayed, the user selects a city and state (with either the mouse or the keyboard). The selected city and state are then "injected" into the city and state textboxes on the page.
For a task like this, it's important that you have a postal code database. There are many commercial ones available, but for this example we used a U.S. postal code list from GeoNotes.org. It is free and licensed under a Creative Commons license. While it probably isn't good enough for heavy-duty production use, it is surprisingly complete (with more than 43,000 postal codes with corresponding cities and states). After downloading the list from GeoNotes, that data was imported into a file on the IBM i.
The JavaScript for this PostalCode lookup is nearly identical to that of the Status lookup. That code can be seen here.
The User Experience Counts!
The quality of your applications' user experience counts. It minimizes or eliminates data entry errors and adds power and functionality to your IBM i application portfolio. This product review shows just one way ASNA can help you provide the best UI possible for your users!
LATEST COMMENTS
MC Press Online