Nathan M. Andelin   November 2016

IBM i Modernization - The User Interface

(Part 7)

This piece introduces the idea of UI widgets and how they might improve the application experience for end-users. UI widgets combine layout (including styling), content (i.e. text, graphic), event listeners (i.e. mouse and keyboard events) and event handlers (functions that often change the widget's visual appearance).

While styling enhances the visual appearance of page elements, event listeners and handlers implement behaviors that may assist with data entry and navigation.

The HTML specification includes a number of standard UI widgets that are used for data entry (i.e. radio buttons, check boxes, drop-down lists, input elements, push buttons). In my experience, replacing these standard components with alternatives available in UI frameworks has not been helpful to end users. However, styling them, extending them and supplementing them may improve the application experience quite a bit.

UI Widget Frameworks

Settling on and standardizing on a UI widget framework can be difficult due to the prodigious variety in styling, behavior, and programming interfaces available. Technical jargon employed by framework developers and promoters is a problem.

I personally dislike defining widgets via JavaScript language & JSON constructs. That's mostly a matter of taste. I prefer using standard HTML elements. Then enhancing them with CSS styling. That's partly due to the availability of editors that assist with code completion. Also partly due to HTML and CSS being ubiquitous standards.

A library's complexity should be considered. Frameworks introduce constraints in addition to functionality. Many UI frameworks are overly scoped and excessively engineered.

Perhaps relevant to end-users might be a framework's size, required downloads, and how much overhead a framework might add to an application. Mobile clients with cellular networks are particularly affected.

For application modernization, I suggest a strategy whereby standard HTML and CSS style sheets are used to define basic widget appearance and behavior. Then use small JavaScript frameworks or modest amounts of custom JavaScript to attach event listeners and handlers that implement prudent (discreet) behavioral enhancements.

Simple Sample

Developers coming from an IBM i green-screen paradigm understand the role of sub-files in display files; They show lists of rows and columns on screens. HTML tables provide similar appearance and functionality.

Moreover, tables can be visually enhanced by attaching styling to their rows, columns, and the table itself. Tables can be wrapped in other containers, that can be styled to look like components (i.e. attach scroll-bars). Finally, event listeners and JavaScript event handlers extend functionality beyond anything available under the green-screen paradigm.

The Phones Application that is embedded below shows how a simple HTML table might be transformed into a UI widget that implements behaviors in response to mouse and keyboard events.

Phones


An ordinary HTML table has been transformed into a UI widget. It has been enhanced by alternating background colors for odd and even rows. The current row is highlighted. Mouse clicks, up-arrow, and down-arrow keys may be used to select rows. The current row is automatically scrolled into view if necessary.

The phone image is changed when a new row is selected. So the table and image can jointly be viewed as being bound together - like a multi-component widget.

Key-press Behaviors

Let's review the key-press behaviors that have been attached to the table:

  • Up-Arrow (navigate to the prior row).
  • Down-Arrow (navigate to the next row).
  • End-Key (navigate to the last row).
  • Home-Key (navigate to the first row).
  • Shift-Down-Arrow (select current and next rows).
  • Shift-Up-Arrow (select current and prior rows).
  • Ctrl-End-Key (select all rows from current to the end).
  • Ctrl-Home-Key (select all rows from current to the first).
  • Ctrl-A (select all rows).

Mouse-Click Behaviors

Let's review the mouse-click behaviors that have been attached to the table:

  • Click (select a row).
  • Ctrl-Click (multi-select individual rows).
  • Shift-Click (multi-select a continuous range of rows).

How Does It Work?

Let's begin by reviewing the HTML.


<h1 id="phead">Phones</h1>
<p style="height:400"><img id="imgx"></p>
<div class="content" style="box-shadow:4px 4px 2px #718BA4;">
 <table id="tb" ht-container="phones"
 ht-href="../../phones/phonerow.html"
 ht-jref="../../phones/phones.json"
 ht-repeat ht-cache ht-after="after_phones()"
 width="100%" height="100%" cellpadding="6" cellspacing="0">
 </table>
</div>


Standard HTML and CSS elements are used to define layout and basic behavior. However this application uses a framework that dynamically generates table rows and cells at runtime by merging an HTML template phonerow.html and a JSON array phones.json.

The framework that merges HTML and JSON was introduced in Part 6. Let's review it again here by beginning with the following attributes assigned to the table.

  • ht-container="phones" (names a container into which merged content is placed).
  • ht-href="../../phones/phonerow.html" (refers to an HTML template).
  • ht-jref="../../phones/phones.json". (refers to a JSON data object).
  • ht-repeat (instructs utility to add a row for each item in a JSON array).
  • ht-cache (instructs utility to cache the HTML template in the browser).
  • ht-after="after_phones()" (instructs the utility to invoke after_phones() after completing the merge).

Now let's review the the custom JavaScript pertaining to the application (phonetbl.js).


function after_phones() {
  tb = new Table('tb');
}


The after_phones() function is invoked after completing the HTML-JSON merge that generates the table's rows and cells.

tb = new Table('tb') creates a new Table() object and returns a reference to it. The table's id (i.e. 'tb') is used to specifically identify the table.

That's all that's needed to transform a standard HTML table into a widget that implements relevant visual attributes and behavior.


function _selectRow(row) {
  var i = row.getAttribute('ht-index');
  $('imgx').src = ht_containers[0].json[i].imageUrl;
  $('phead').scrollIntoView(true);
}


The _selectRow() function is automatically invoked by the Table() object whenever users select a new row. I'm using it to change the image URL, that is referenced in the JSON array object.

Framework Components

The framework supporting this interface is referenced via the following <script> tags in the page's header section:


<script src="../../rdweb/apps/common/scripts/binders.js"></script>
<script src="../../rdweb/apps/common/scripts/keyhandler.js"></script>
<script src="../../rdweb/apps/common/scripts/tables.js"></script>
<script src="../../rdweb/apps/common/scripts/ht_merge.js" defer></script>


The framework size sums to something like 40KB (un-compressed), which is tiny in comparison to typical frameworks that include UI widgets and client-side infrastructure.

Much can be accomplished by a relatively small amount of JavaScript without burdening bandwidth and client-side compute resources.

Conclusions

  1. Widgets can improve the appearance and behavior of the user interface.
  2. Widgets can improve end-user productivity.
  3. Widget libraries tend to be overly scoped and sized.
  4. UI frameworks tend to be overly scoped, overly sized, and excessively engineered.
  5. Standard HTML elements offer a solid UI foundation.
  6. Supplemental widgets can be added via small frameworks & custom code.

Continued in Part 8