Skip to Content

How to check whether a WD Java Input Field marked as “required” contains any data


This blog assumes that you know how to write a Web Dynpro application and have a functional SAP NetWeaver Java AS or a suitably deployed Tomcat server. It will not provide any further explanation beyond stating what steps need to be performed.

The main functionality for this process is an extension of the generic UITreeVisitor class that is documented in section 10.4 of my book “Inside Web Dynpro for Java” (pages 327-331)  If you don’t yet own a copy of my book, then shame on you!  🙂The only coding needed in the component controller is that necessary in wdDoInit() to create two elements in the InputData context node.  You can download the wdDoInit() code snippet here .

Notice that both messages are of type “error” and that they have a single parameter identified by “
After you have created these messages, you must save all your changes by pressing Ctrl-Shift-S.  This forces the code generator to run and allows you programmatic access to the declared messages.

    1. Open the view editor and create the following view layout:
      Set the RootElement’s LayoutManager to MatrixLayout
      !http://whealy.com/images/Web%20Dynpro/Input%20Validator/ViewLayout.png|height=496|alt=View layout|width=588|src=http://whealy.com/images/Web%20Dynpro/Input%20Validator/ViewLayout.png|border=0!

      The easiest way to add these UI elements is to right-click on the RootElement in the outline view and select “Apply template”.  Then select “Form” and add all the attributes in the node InputData.

    2. In the outline view, Ctrl-click on each of InputField UI elements in order to select all of them.  then change the “state” property from “normal” to “required”.  A red star will then appear next to the corresponding label field.
    3. Create an action in the view controller called “DoButtonPush”.  Give this action a parameter called “Action” of type integer.  Make sure that this action is a validating action.
    4. Now add two buttons to the screen.  As can be seen from the screen shot above, these buttons are for the “Previous” and “Next” functionality.  Assign the same action “DoButtonPush” to both buttons.
    5. In the Outline view, right-click on the “Previous” button and select “Parameter Mapping”.  In the popup window, press the “Create Constant” button and assign the value 0 to the action parameter.
    6. Repeat step 11 for the “Next” button, but this time, assign the constant value of 1.
    7. Switch to the Navigator view (the tab next to the Web Dynpro Explorer) and expand the “Resources” tree until you reach the “input_validator” directory.  Here, create a new Java file called UiTreeVisitor.java as per the screen shot below
      !http://whealy.com/images/Web%20Dynpro/Input%20Validator/ResourcesTree.png|height=410|alt=Resource tree|width=308|src=http://whealy.com/images/Web%20Dynpro/Input%20Validator/ResourcesTree.png|border=0!

Download the coding for the UiTreeVisitor class and insert it into this file and then save it.

    1. Open the Java editor for the view controller InputValidatorView.  Download the controller coding for each of the following methods and insert it at the appropriate place in the controller:
    1. Now organize the view controller’s imports by pressing Ctrl-Shift-O and save the changes.
    2. Create a new application called InputValidatorApp.
    3. Deploy and run this application and you should see something like the following screen
    4. h2. Running the application

!http://whealy.com/images/Web%20Dynpro/Input%20Validator/StartScreen.png|height=400|alt=Start screen|width=500|src=http://whealy.com/images/Web%20Dynpro/Input%20Validator/StartScreen.png|border=0!

If you simply press the “Next” or “Previous” buttons, you will swap the display between the two elements in node InputData.

Now blank out one of the fields and try pressing “Next” or “Previous”.

!http://whealy.com/images/Web%20Dynpro/Input%20Validator/ErrorScreen2.png|height=400|alt=Error screen|width=500|src=http://whealy.com/images/Web%20Dynpro/Input%20Validator/ErrorScreen2.png|border=0!

You will see an error message that is linked to the UI element that is missing an input value.  Click on the error message at the bottom of the screen and the cursor will be relocated to the field in error.

 If you blank out multiple fields, then you will get multiple error messges, each linked to the approriate UI element.  The error message is tailored to whether the input field should contain a string or numeric value.  This functionality can be extended if you wish to create specific messages for time and date fields.

!http://whealy.com/images/Web%20Dynpro/Input%20Validator/ErrorScreen1.png|height=614|alt=Error screen with multiple messages|width=500|src=http://whealy.com/images/Web%20Dynpro/Input%20Validator/ErrorScreen1.png|border=0!

h1. Caveats

There are a few things to note about this solution!

    This is fine as long as you are disciplined to restrict your access to read-only.
    Please do not start noodling around with IWDView by adding new UI elements outside the scope of wdDoModifyView()!  You risk doing bad things to your data by potentially causing context supply functions run multiple times, or causing the framework to render the screen multiple times.

    The vector of messages passed to the UiTreeVisitor class is rather kludgey, but it saved me having to noodle around with reflection in the UiTreeVisitor class in order to discover what messages were contained if I’d passed the component’s IMessage class.

    To report this post you need to login first.

    3 Comments

    You must be Logged on to comment or reply to a post.

    1. Sebastian Lenk
      Hello Chris,

      great Blog. Will try this next time I a have a required field to implement.

      I’ve tried a different approach. But I’m not sure if this will work in a real life scenario. I like to use the Annotations of a JPA Entity for Validation like the Seam Framework does.

      Let’s assume we have application using EJBs with JPA for data persitence.
      I consume the EJBs directly without the using a Model.
      {code}
        public void wdDoInit()
        {
          //@@begin wdDoInit()
             wdContext.currentContextElement().setEchoEntity(new EchoEntity());
            
             try {
                Context ctx = new InitialContext();
                
                echoLocal = (EchoLocal) ctx.lookup(“demo.sap.com/echo_ear/LOCAL/Echo/com.bosch.echo.session.EchoLocal”);
           } catch (NamingException e) {
                wdComponentAPI.getMessageManager().reportException(e);
           }
          //@@end
        }
      {code}

      Because it is not posibble to display the properties of the EntityBean I’ve created a node in the view with same properties like my Entity Bean, where I copy them.
      For validation I’ve created a generic methods that checks for example the length for every property. See code:
      {code}
        //@@begin others
        private boolean validate(EchoEntity echoEntity) {
                try {
                     Field[] fields = echoEntity.getClass().getDeclaredFields();
                     for (Field field : fields) {
                          //field = echoEntity.getClass().getDeclaredField(“input”);
                          Column column = field.getAnnotation(Column.class);
                          if (column!=null && column.length()<echoEntity.getInput().length()) {
                               IWDAttributePointer attrPointer = wdContext.currentContextElement().getAttributePointer(field.getName());
                               String fielLabel = attrPointer.getAttributeInfo().getSimpleType().getFieldLabel();
                               wdComponentAPI.getMessageManager().reportContextAttributeMessage(attrPointer, IMessageEchoComp.FIELD_TO_LONG, new Object[]{fielLabel, column.length()});
                          }     
                     }
                } catch (SecurityException e) {
                     wdComponentAPI.getMessageManager().reportException(e);
                     e.printStackTrace();
                }
                return wdComponentAPI.getMessageManager().hasExceptions();
           }
        //@@end
      {code}

      In my small example it works, but as WDJ beginner I’m not sure if this will also rock in a real life scenario?

      Best Regards
      Sebastian

      (0) 
      1. Chris Whealy Post author
        Hi Sebastian
        Your solution looks fine, but as you said, it takes a very different approach.
        In my solution, the driver is the “state” property belonging to the UI element IWDInputField.
        After each round trip, the UiTreeVisitor parses the UI element hierarchy looking firstly, for elements of class IWDInputField, and the secondly, checking whether the “state” property has been set to “required”.  If it has, then the context attribute to which the input field’s value property is bound is checked to see if it contains a non-initial value.
        Your solution (I assume) arbitrarily checks the values of all fields in the EntityBean – irrespective of whether that value was bound to a UI element or not.
        In other words, your process (which I think will work perfectly well) is not driven by whether the user is required to enter a value through the UI.
        Regards
        Chris W
        (0) 
    2. Young Hwan Kim
      Great blog!

      I find new method checkAndReportRequiredFields() of viewcontroller in CE7.2.
      Does it have the same functionality as you mentioned here?

      (0) 

    Leave a Reply