if you think “Dynamic UI Generation – what is so special about that? I’ve been using that for years”, then this might be just the right blog for you as well as for those who are new in this area. Why? Because one focus point of this blog is to explain the problems of dynamic user interface generation as well as the wrong use of it.
If you want to follow my example closely, you can download the completed project from here: example
This project has been created in SAP NetWeaver 7.0 (2004s).
When you should not use dynamic user interface generation
If in any way possible, you should always design your views at design time, not create their layouts at runtime. Now, why’s that? Well, for once it is certainly easier to make mistakes by writing the code instead of using the drag&drop features of the NetWeaver Developer Studio (NWDS). Of course, with sufficient trial and error you will finally end up with the layout you wanted to have when you create the user interface elements in the coding, but it sure is easier to use the WYSIWYG features the NWDS has to offer. Another important reason to use dynamic user interface generation as little as possible is the more difficult maintenance of the code that is to be implemented.
You might say that you have a bunch of user interface elements on the same view, but you only want some of them to be visible at the start of the application and some others only be visible after a certain user interaction. Take the attached project as an example: an additional InputField for the state could show up for all users that have selected their location to be in the US during a registration process. Yet there is no reason to add that field to the user interface programmatically: as you know that this element might be needed in some cases, you can add it to the view at design time and simply make it invisible until it is required.
Now, how do you do that? First, you need to create an additional context attribute for all elements that you want to be invisible at the same time (lets call that a visibility group, of which you can have many). It must be of the type WDVisibility (com.sap.ide.webdynpro.uielementdefinitions.Visibility) and will control the visibility of all the elements in that visibility group simultaneously. In the next step, you should add the elements of your visibility group to the view, exactly to the spot you want them to show up on later. Finally, bind the visible property to your newly created context attribute.
And how do you control those elements’ visibility now? Well, if the user takes an action (like pressing a button or changing the lead selection of your dropdown element), some methods will be called. To stick with our example, when the user selects a new entry from the country dropdown list, an event called onSelect will be triggered. Within the associated EventHandler method, you can now change the context. In this case, you will want to change the previously created context attribute to VISIBLE, if and only if the user had selected USA from the dropdown list. In any other case, the value shall be reset to the initial setting. As you might have realized, there are two settings that seem to hide the elements: NONE and BLANK. So what is the difference between them and which one do we need here?
- WDVisibility.BLANK makes the element invisible, but preserves the space it would take up if it were visible
- WDVisibility.NONE makes the element invisible and does not preserve the space it would take up if it were visible
As the additional InputField called state shall only appear when the user has selected USA as country, it will be the better course of action to use NONE in this case. The option BLANK is more convenient if you want to preserve the layout. Well, your coding could look like this in the EventHandler now, assuming you called your attribute for visibility visibility_state:
Don’t forget to set wdContext.currentContextElement().setVisibility_state(WDVisibility.NONE); in wdDoInit() to have the elements for state invisible when the application starts!
When should you use dynamic user interface generation?
As mentioned before, the answer is “as little as possible”. But of course there are situations when you have no other chance as you simply don’t know which or how many elements can be visible to the user at a given time.
- Question: If the user selected female as gender on my registration view, he will have more and different questions on the next view than if he had selected male. Should I use dynamic user interface generation here?
- Answer: No! As you can determine which and how many questions will be displayed upon the user’s selection, you can create the necessary fields at design time and use the visible property again.
- Question: If I have an InputField where the user can enter the number of his children, and on the next view I have InputFields for the children’s names, do I need dynamic user interface generation in this case?
- Answer: Yes! This would be an appropriate place to use dynamic user interface generation, because you (the developer) can not determine the number of children the user will have, so you can not know how many InputFields you have to provide on the next view.
Well, in order to have different questions, you can introduce a new context attribute in the SecondaryView to hide some questions for the males. However, you will need to use dynamic user interface generation for the children’s names here, so what do you have to do?
First of all, only change the view layout in the method wdDoModifyView()! To make sure that you don’t (have to) recreate the view with every roundtrip, there is a boolean variable called firstTime, so it’s easy to make sure the elements are only inserted when the view is initialized. Inserting new elements into the view is quite simple: you create a new element and attach it on an existing element of the view, for example the RootElement. To have an InputField for each child’s name and an according label, you can do that in a loop as follows:
As you see, we also had to create a context node with an attribute here, because the InputFields o be created have to be bound to a context attribute. Of course that could be created in design time as well, giving the chance of a slight overhead (in case the user has no children). The result looks similar to this:
Dynamic user interface generation can be a quite powerful tool in some situations, but it has to be used cautiously. I hope you understand the problems that are coming with this method a little better now so you can start using this the right way.
Further information can also be found in the wiki: https://wiki.sdn.sap.com/wiki/x/Odc
Have fun with Web Dynpro,