Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

Slow, but gentle...

In real-life applications there are some operations that  take more then "user-thinking" time (up to half a second for  desktop applications, two seconds for web applications). Actually,  this is a time before user gets nervous and tries to resubmit  data or to perform other "destructive" actions. Typically, UI  developers use some kind of progress indicator or just an animation  that informs user about long-running operation and (optionally)  provides progress information either as percent of job done, or  number of items processed, or both.

WebDynpro HTML client is not an exception here (probably,  SmartClient as well). When user invokes operation that requires  server action (Button or LinkToAction click, Tablelead selection  change etc), client-side JavaScript issues HTTP request to server.  Moreover, certain changes to client UI is done. First, the whole  HTML page is covered with transparent DIV element. This is well-known  "glass pane" trick - user still sees content of page but may not  interact with it while all events (key press, mouse clicks etc) are  "eaten" by glass pane. By the way, certain WD versions have small  CSS/JavaScript bug - the DIV used as glass pane has larger size  then necessary. Technically, size of region reserved for scroll bars  is not subtracted, so you can see how scrollbar(s) appears when  you are invoking certain action and disappears afterwards.  Second, client-side JavaScript timer is set for approximately one second.  If server-side processing takes more then one second, the timer  fires and WD client shows well-known animated image centered on  page that stays until operation completes and response is returned.

Note that it's just internal details of current implementation,  things may change in future releases. Anyway, WD HTML client provides  good enough implementation of "progress indicator" out of the box.  However, there are some situations when this functionality is not  enough or even not available at all.

What (the heck) I'm waiting for?

The first issue is that you can not alter indicator in any way.  Most importantly, you can't add any descriptive message/explanation  for currently executed action, kind of "Importing CSV file (10 Mb),  please wait..." To overcome this limitation (up to certain extent, sure),  you may use WD Timer control (do not confuse with JavaScript timer).

 

Let us imaging that you in fact have to display explanatory message  when user invokes long-running operation. The algorithm is the following:

  1. Create TextView for message; bind its "visibility" property to context  attribute of type Vsibility; either set text of TextView to some static value,  or bind it to string context attribute.
  2. Create Timer control; bind its "enabled" property to context attribute  of type boolean; set interval of timer to 1 (one second, the lowest possible  value).
  3. Create and assign action for Timer OnTimeout event.
  4. In wdDoInit of view controller set value of "visibility" attribute (related  to TextView) to WDVisibility.NONE and "enabled" (Timer) to false.
  5. Now, in action handler for Button or LinkToAction or whatever else  you have, do the following:  
       
    1. update text of TextView via context attribute if necessary;
    2.  
    3. make TextView visible via context attribute;
    4.  
    5. make Timer enabled (also via context attribute);
    6.  
    7. optionally you may hide some other UI controls
    8.  
      Do not invoke long-running operation here!
  6. Finally, in OnTimeout action handler execute the following sequence:  
       
    1. make TextView invisible again;
    2.  
    3. disable Timer;
    4.  
    5. execute long-running operation;
    6.  
    7. if you performed 5.d, then revert back visibility changes for    other controls.
    8.  

From user point of view, this will result in following sequence: user  clicks a button (or invoke action in some other way); then it sees message  about long-running task; shortly progress indicator appears; finally,  progress indicator is removed and result is shown.

The solution has two drawbacks. We force user to wait yet another second  (timeout of Timer control), so apply this technique only when operation takes  at least 5 seconds. Anyway, if it takes less then 5-3 seconds almost no one  will read your message 🙂 Plus you must avoid placing a message at center of  screen - it will be overlapped by indicator itself.

 

Ready! Steady! Go!

The second issue with built-in WD progress indicator is that it's not  invoked when application loads. Imaging a scenario, when application has to  show user-specific dashboard (think about UWL inbox) on initial screen, so  you make back-end call from wdDoInit of component controller. Loading of such  dashboard requires selecting large set of items (probably from several back-end  systems), filtering them, applying permissions etc. So application start time  takes several seconds.

 

Also your customer and usability experts inside your company agree that  such delay is acceptable, you noticed some unpleasant effect - the well-known  and lovely WD loading indicator is not shown at all! What user sees for  3-5 seconds is just ugly blank screen! Es geht nicht.

The only way to fix WD behavior is to avoid loading data on startup. Seriously!  My solution can be described as the following (again, Timer to the rescue):

  1. Create one additional view for main application window, kind of  welcome screen.
  2. Make this view default on window, link it via plugs with "real" (or "main")  view
  3. On welcome screen place some "Loading..." message as TextView, plus  application name, plus copyright notice, plus whatever you want (consult  splash screen design of any desktop application) and enabled Timer control  with one second delay. Again, make sure that any texts are not located at  center of screen... for known reason. By the way, you may create empty view with  single Timer control - you get extremely ascetic splash screen 😉
  4. In OnTimeout action handler of Timer, just fire plug to "real" view
  5. "Real" view calls public method of component controller that actually  loads data. Important: this must be user-defined method, not wdDoInit hook!
 

How it works? User sees your welcome screen almost immediately.  After short delay loading indicator appears. At this time Timer has already  fired event, and server-side part of WD application is loading data. When data is available, indicator is removed and complete dashboard is shown.

 

My previous solution to this problem was a bit trickier. It requires re-start  of application (do not worry, not in Visual Administrator, just redirect to another URL), usage of deprecated IFrame control and pair of Flash movie and animated GIF  image. Here are the sources for this outdated implementation, use "Save as..." link command and rename to *.zip after download.

8 Comments