The EGL Rich UI Manual is here:
One nice design feature of EGL Rich UI is that UI components can be organized into self-contained, independent units. This makes it easy to reuse components in different applications and within different parts of the same application. Infobus, which was described earlier, provides a way for components to talk to each other, without necessarily knowing about each other. This enables new components to be snapped into an application without disturbing the other components. This approach also saves you from creating enormous RUI handlers that eventually become a spaghetti code nightmare.
The following example illustrates a good pattern for constructing Rich UI applications. You will notice a main "driver" RUI handler (PartDetailsApplication) that defines the basic layout of the application. It references other RUI handlers that contain the client-side logic of the application. Each RUI handler can operate independently from the other handlers and there does not need to be any hard dependencies between the handlers. This makes applications more modular, and allows for greater flexibility later as business requirements change and new requirements are introduced.
Below are descriptions for the different components that make up a sample (and very simple) application that provides sporting good part information to a user.
PartListHandler is a RUI handler that displays a grid (data table) of parts to the user.
Here is the code:
The grid is populated from a static array of PartRecord objects (typically data would be retrieved via a service call, but, for the sake of simplicity, the data is hard-coded). When a row in the table is selected, the selectionChanged function of the RUI handler is called (this happens because GridSelector provides a mechanism whereby a listener can be notified when a row is selected). The selectionChanged function gets the selected part from the grid and publishes it via the InfoBus. The name of the message (com.ibm.samples.rui.part) is defined in a constant variable, PART, defined in a basic library (*PartDetailsLibrary*). It is recommended to define InfoBus message names as constants in a library (this avoids typing mistakes and makes maintenance easier if the name needs to change for some reason).
When the "com.ibm.samples.rui.part" message is published, the partCallback function is called (this part picture RUI handler knows nothing about the part list handler). A quick check is made to ensure the incoming message name and data object are what we expect (because we subscribed to an explicit event name, we really don't need to perform this check, but it's always safe to double-check since applications grow in size and complexity over time). Because the data object is a PartRecord, we can grab the selected part's picture file name, construct a URL to the image, and set it on our Image widget (effectively showing a picture to the user).
Here is how the completed application appears:
Happy (almost) New Year, everyone!
I've been busy with a non-EGL project, and now I'm back to work with EGL. The EGL Rich UI book is well along conceptually, and I'm working to incorporate the many changes that occurred between the Alphaworks version of Rich UI and the production release of 7.5.1.
Stay tuned here and I'll bring you the blow by blow.
Many EGL Rich UI applications are migration targets from a legacy desktop application developed in VisualAge Generator, PowerBuilder, VisualBasic, or similar technologies. Personally, I think menus have no place in web2.0 applications. Just go find the menubar in gmail, or in Google Finance. They're not there. However, if you have to maintain superficial compatibility between the old application and the new one, and you really need a menu, EGL Rich UI comes with a powerful menu solution that lets you completely customize and style your menu.
Those of you who are already dabbling with menus will discover they are hard to use in the RBD. What is happening here is that our Text UI and Rich UI technologies are fighting over the same types being available for lookup. Namely, we automatically include the Text UI's Menu and MenuItem on the search path. This is for historical reasons. We are looking at IDE solutions to better separate the search paths, without ruining the lives of existing CUI programmers. For now, if you use menus in EGL Rich UI, simply write the import statements by hand. Ctrl-Shift-O, nor Ctrl-Space, will introduce the import statements automatically.
Anyway, back to the power of menus. With all the flexibility that comes with the menus, allowing you to attach behaviors, etc, a price is paid for ease of use. When Jon Sayles and I talked about his upcoming Rich UI training materials he is working on, he mentioned the need for a simpler menu. One with just text, and one event handler. One that is not so flexible perhaps, but one that works quickly.
What you will see below is a Menu implemented using our general solution, including defining a behavior to set styles and handle events. Rather than setting up the menu with MenuItems, and gobble together the entire menu, I tried to make the declaration as simple as possible, using just an array of String. It limits what the menu can do. It has no sub-menus, and no icons in the menu, and all menu item elements look the same. Imagine a virtual slider with on the left side ease of use and abstration, and on the right side full detail with maximum power. SimpleMenu sits way on the left. Our Rich UI menu solution sits way on the right. You may come up with a menu solution called IconNestedMenu that sits somewhere in the middle. I find that aspect of software design the most intriguing: where to put your solution on that imaginary slider.
To create a SimpleMenu, you say the following:
You specify one or more listeners, and introduce each menu (we add three menu in this sample). Each menu has a number of options that will be shown when the menu is activated. This is what the menu will look like:
The menubar is grey, and the menus are white. When the mouse is hovered over a menu title or menu item, the background turns to a shade of blue. We handle a few extra events to hide the menu automatically, and close existing menus when hovering to another one on the menubar.
When a menu item is selected, the SimpleMenu will trigger the listeners that have registered:
All styling for the menubar and the menu items is done in CSS, so you can control the look and feel easily. This is what the CSS looks like originally:
Changing the look and feel is easy. For instance, if you change the background color to the menu title and item to this:
you will get this result:
The implementation of SimpleMenu uses the existing Rich UI menu, adds a behavior to it, and converts our simplified list of menu item strings into instances of MenuItem and set up the menu.
When a SimpleMenu is created, we use the exsiting menu and set up a behavior:
The hightlightMenu behavior function is called by the Rich UI menu each time a menu is created and allows us to customize the menu as we see fit. In our case, we set up event handlers and styles on the menu as follows:
When we move the mouse around and enter a menu item, we want to show it and also close any menu item that is already open. The enterTitle function takes care of that:
The enterTitle function is called whenever the mouse enters a menu item. We now want to inform all the other menus to close themselves. To avoid us having to go back to the menubar and ask it to close the other menus for us, we use the InfoBus to generate an application level event that is broadcasted to all the other menus.
As a result, each menu will be informed when it should close itself. This is how numerous menus can talk to each other without needing a third party to help out in the communication.
esimone_clearblade 270000E5WV Tags:  rui service eglcafe web2.0 clearblade 1 Comment 8,601 Views
I've been playing with RBD 7.5 and Rich UI over the past week or so and this is very cool stuff! I've been following Chris Laffra's posts on the Rich UI blog and implemented a couple of his Rich UI solutions.
Using Jon Sayles' EGL training material, I created the "Let's Go To The Movies!" web service example with a Rich UI interface using nested grids and the service monitor.
I'm beginning work on the movie filtering capability. If anyone has ideas on how to implement this please let me know.
The code is attached. Check it out.
Grids are powerful widgets, and with the support for behaviors that we added, it is possible to style the widgets exactly how you want it, replace cells with complex widgets, do drag and drop, etc.
In this snippet of code, I show how to use a behavior to filter out contents to be excluded from the cells being shown.
The salient function is the filter function. It scans the cell contents and rejects the line by removing the table row from the table.
EGL Rich UI makes it really simple to invoke REST or SOAP web services and to convert the message parameters and result into EGL Records. However, sometimes, the service does not work and you feel like you are stuck. In this blog entry I will share some best practices we developed on the Rich UI team for dealing with services that don't respond as you expect them to.
Most people start out with using the following syntax to make a service call:
When the foo.bar service is invoked, a response will be returned some time in the future, and then the callback function is called. It gets interesting when the service is not available, or when we pass invalid parameters to the service call. How to deal with exceptions?
It would seem like the right thing to do. Call a service. When something bad happens, handle the exception. However, service calls consist of two steps. First, you send out the service request, which is really dealt with in the "call" part of the statement. The service request is sent over the wire, and control immediately continues to the next line. No exceptions will happen at this point, as you can assume we will always be able to send the request over the wire. Now, when the response comes back in the future, the callback is invoked. If the server responds with an error message instead, we have no real place to report the error to the code. This is why we have a special syntax on the call statement looking like this:
Now, each time the service is unresponsive, or the server complains about our parameters being incorrect, the handleException function will be called, and we can take evasive actions.
As you can see, if a service call is successful, we will add an OK icon with green background. Otherwise, we add an ERROR icon with red background.
I'm very happy to announce that RBD 188.8.131.52 is finally available, a little holiday gift from us to you!
This fix pack contains a lot of fixes, especially in the areas of COBOL generation, Java generation, debugger, and page designer. So everyone who is using RBD 7.1.x should install it.
You can download the fix pack from the support site: IBM Rational Business Developer Version 184.108.40.206.
If you deploy your applications on zSeries, you should also get current maintenance for Rational COBOL Runtime; there are a couple of PTFs that need to be applied.
In addition to bug fixes, this fix pack contains a number of small enhancements:
Lisa [Read More]
In an earlier blog post, we showed how grid cells can be replaced with checkboxes and dynamic editors. In this exercise we will go even further and add a nested grid inside a grid.
First we declare the recursive data structure we will use for our grid:
Then we define the columns we want to show and add it to the Grid:
The result is the following grid:
To replace the list of employee staff members with a nested grid, we define a new cell behavior and add it to the grid declaration:
The showStaff cell behavior converts the ids "3,4," into a data array, creates a new grid from it, and then replaces the original cell's contents with this newly created nested grid. If no staff is available, we added a stylized indicator.
The function that parses the staff member is needlessly complex in this example. In reality you could call a service for this employee and retrieve the list of staff members as an array. That array can then be used to populate the nested grid.
The final result is this: