16 Jul 2011

Using attribute's custom properties in model layer

Sometimes we need to change properties of the VO's attributes dynamically at run time, depending on some business logic. Sometimes we need  to pass some extra information from the model layer to the view layer. We can use attributes' custom properties.

For example, I need to change attribute's label and make it readonly on the fly. In my ViewObjectImpl class I have the following method:

 public void setCustomHints() {      
     AttributeDefImpl attr = ((AttributeDefImpl) findAttributeDef("DepartmentName"));
     attr.setProperty("customLabel", "The custom label");
     attr.setProperty("readonly", Boolean.TRUE);
 }

The setCustomHints method is going to be executed on a commandButton's action. And the  jspx page contains the following piece of code:

          <af:inputText value="#{bindings.DepartmentName.inputValue}"
                       
                        label="#{bindings.DepartmentName.hints.customLabel}"
                        readonly="#{bindings.DepartmentName.hints.readonly}"
                       
                        columns="#{bindings.DepartmentName.hints.displayWidth}"
                        maximumLength="#{bindings.DepartmentName.hints.precision}"
                        shortDesc="#{bindings.DepartmentName.hints.tooltip}"
                        id="it4" partialTriggers="cb1">
            <f:validator binding="#{bindings.DepartmentName.validator}"/>
          </af:inputText>
          <af:commandButton actionListener="#{bindings.setCustomHints.execute}"
                            text="setCustomHints"
                            disabled="#{!bindings.setCustomHints.enabled}"
                            id="cb1"/>

Additionally, I set up default values for customLabel and readonly custom properties at the VO's definition page:


And finally, we've got the following result:













The sample application for this post is available.

2 Jul 2011

How to use preRenderComponent event in JDev11g R2

There is very common use case when we need to do some preparation work on initial page rendering. For example, we need to do some initialization stuffs like displaying error messages or disabling/enabling tool buttons depending on the model's state and so on. As usual we create some phase listener or implement BeforePhase  event of the f:view tag. The issue is getting more complicated for task flows with page fragments. Page fragments don't have the f:view tag.
JDeveloper 11g R2 allow us to resolve the issue in elegant and easy way. JSF 2.0 specification supports new f:event tag. It has two simple attributes: type and listener. We can attach f:event tag to any of the page's components meaning the component listens to the event of the specified type and in case of event firing calls correspondent listener provided by some EL expression in the listener attribute.There are some predefined event types: postAddToView, postValidate, preRenderComponent, preValidate. Let's focus on  preRenderComponent event. It fires exactly before rendering the component. In the following example we have commandButton with preRenderComponent event listener. The listener enables or disables the button depending on some conditions:

    <af:commandButton text="commandButton 1" id="cb1">
      <f:event listener="#{managedBean.listenForEvent}" 
               type="preRenderComponent"/>
    </af:commandButton>

And implementation of the listener looks like this:

    public void listenForEvent(ComponentSystemEvent componentSystemEvent) {
        UIComponent cb = componentSystemEvent.getComponent();
        if (cb instanceof RichCommandButton)
            ((RichCommandButton) cb).setDisabled(getSomeCondition());
    }