|
Blogs
Nearly in every new web development project I hear the requirement to provide tables with customizable layouts. This ability is known by customers from the SAP ERP world as an ALV (ABAP List Viewer) and is always wanted in web UIs. Unfortunately, such a functionality is only available in Web Dynpro for ABAP and in the Visual Composer CE 7.1 so far. There is no such widget in the Web Dynpro for Java. The most important functionality of ALV is the ability to hide unneeded columns of the table. The user can easily select columns important in his working context. That also helps to avoid horizontal scroll bar in case of very long tables. In this blog I will show how to implement such a functionality generically to be able to use it later with 3 lines of code on every table placed in the Web Dynpro for Java view.
Requirements and challenges of the implementation To provide the functionality of hiding/showing table columns we have following challenges:
Sounds rather tough... Fortunately, playing a bit with Composition Environment 7.1 EHP 1 I was able to find the solution for all of these points. Keep in mind - the solution will only work with 7.1 EHP 1 but can be downported to 7.1 (with no EHP 1) using some "workarounds". The presented code will however use only "public" and "allowed" APIs and documented features and hence will need 7.1 EHP1.
Representation of the configuration The CE 7.1 brings a very nice functionality of context menus. A context menu can now be shown on nearly every widget in the view. The advantage is, that we can create such a menu "on the fly" if the user clicks on a widget with the secondary mouse button. We will use this feature for our functionality (see the picture below). The user will click on the caption of the table and select all columns to be shown or hidden. If the column is excluded from the configuration via API, it will not appear in the context menu.
How does it work? To implement such a functionality the standard callback method of the view controller wdOnContextMenu is used (see CE 7.1 documentation). As the user of TableCustomizer you only need to place there following code:
TableCustomizer.showMenu(contextMenuManager, event, "Table1"); //Exclude some columns from customizing TableCustomizer.showMenu(contextMenuManager, event, "Table2", "Key", "Name");
TableCustomizer is the only class you will need for the whole implementation. It can be downloaded in the article (see the link below). Second call shows how to exclude some columns from the customization. The first two parameters are the standard parameters of the callback method. The third one is the id of the table you want to be customizable. The optional variable length arguments are used to define the columns you would like to exclude from the customization (This Java 5 feature is very nice!). The API call will automatically create a context menu if the user clicks on the table header.
Saving the configuration That is probably the most challenging thing. There is no public API to store some personalized information in WD for Java. There are some workarounds (e.g. using portal) but none of them is really nice. Fortunately, CE 7.1 EHP 1 brings some new methods providing access to the HttpServletRequest and HttpServletResponse. They are now public! So we can access them and set cookies from Web Dynpro for Java! And that is the solution we will use to store user settings. The implementation of the TableCustomizer has access underlying HTTP request as follows:
IWDProtocolAdapter protocolAdapter = WDProtocolAdapter.getProtocolAdapter(); HttpServletRequest protocolResponse = (HttpServletRequest) protocolAdapter.getRequestObject() .getProtocolRequest();
To be able to cast to HttpServletRequest we have to add the dependency to the SERVERCORE/servlet standard development component. The complete code can be found in loadFromCookie(String) and storeToCookie(String, String) in the implementation of TableCustomizer.
Loading the configuration Now it is rather clear where to store the user configuration. Let us define where to load it. We need to load the configuration at every first initialization of the view. It's usual to use wdDoModifyView. Following code will do that for you:
if (firstTime) { TableCustomizer.setColumnsVisibility(view, "Table1"); TableCustomizer.setColumnsVisibility(view, "Table2"); }
You will need one call for each table for which the settings (columns visibility) has to be loaded.
Reacting on user interactions The user will click on check box item in the menu to hidden or show table columns. But how to react on these actions in the code? We will create an action in the view which will be used generically for all menu interactions and all customizable tables! I've defined the name of the action in the constant CONTEXT_MENU_ON_TOGGLE_ACTION_NAME = "ContextMenuToggle";. So just create a new action with the name "ContextMenuToggle" in your view.
Only one code line has to be placed into the event handler for all tables: TableCustomizer.menuToggled(wdEvent, wdContext); Both parameters you can pass from the handler and the view. That's all! The tables are customizable now! We can also add some other functionalities into this menu in the future and use them generically on all tables. (Consider generic excel export etc. )
And what is with CE 7.1 without EHP 1? Well, there are no official way to work with cookies on 7.1 without EHP1... So you are welcome to search for workarounds for storing the setting of the user. However there are some inofficial solutions available on SDN... Alternatively you can extend my implementation with some persistency calls (RFC, Database), but I suppose, it will made the code less attractive and reusable.
Is there any hope for NW04 and NW 7.0 to implement a similar functionality? There is no comparable context menu feature in older NW versions. NW 7.0 brings some rudimentary context menus which can only be used on certain view elements. But I suppose it is still possible to implement this solution on them. It is certainly more tricky. NW04 is really the most difficult case. There is no menu functionality at all. So we should definitely use something else...
Attachments I've shared the WD Development component, which will help to understand the whole solution (sca file in the following archive). https://www.sdn.sap.com/irj/scn/index?rid=/library/uuid/4094f301-236e-2c10-13bb-db960051ea1e. Just import it as a local software component. Alternatively you can use only the TableCustomizer class (in the same archive) and use this blog as a guide to run it. Don't forget, you need EHP 1 for running it.
Dimitri Lubenski is a SAP Netweaver Consultant working for Siemens AG
| |||||||||||||||||||||||