This discussion is archived
2 Replies Latest reply: Jan 14, 2013 9:52 PM by jmsjr RSS

EL expression for the render or execute attribute to exclude component ids

jmsjr Newbie
Currently Being Moderated
This is not a question, more of sharing some ideas.


I recently had a need that some input components must only be validated when say, the 'Submit' button is clicked, but NOT validated when say, the 'Save' button is clicked. I cannot rely on the "disabled" attribute of the input component that I needed to conditionally validate, because at the time the commandButton is selected, it is already too late.

So, one way I thought of doing this was to have the components that I do NOT want to validate with the 'Save' button excluded from the 'execute' attribute of the f:ajax tag of the h:commandButton. One problem with this approach though was that, the list of component ids that one would like to potentially validated is quite long. So instead of writing down all the component ids that I want to include in the 'execute' attribute, I actually just want to write the component ids that I want to EXCLUDE from the 'execute' attribute.
<h:inputText id="f_someText" value="#{anotherViewBean.someText}"
     validator="#{anotherViewBean.validateSomeText}"/>
<rich:message for="f_someText"/>
<br/>
<rich:calendar id="f_someDate" value="#{anotherViewBean.someDate}"
     enableManualInput="true" datePattern="dd/MM/yyyy"
     required="true"
     validator="#{anotherViewBean.validateSomeDate}">
     <f:ajax event="change" execute="@this" render="f_msgSomeDate out"/>
</rich:calendar>
<rich:message id="f_msgSomeDate" for="f_someDate"/>
<br/>

<a4j:commandButton id="save" value="Save"
     execute="#{anotherViewBean.includeAllExcept('f_someDate')}" 
     action="#{anotherViewBean.doSave()}"/> 
<a4j:commandButton id="release" value="Release" 
     action="#{anotherViewBean.doSave()}"/><br/>
Although I am using a4j:commandButton, that is simply equivalent to an f:ajax nested inside an h:commandButton.
What you will notice from the above is the EL expression in the execute attribute of the a4j:commandButton:
execute="#{anotherViewBean.includeAllExcept('f_someDate')}"
This EL expression returns a space delimited list of component ids of all UIInput and UICommand ... minus the the ones that you want excluded. In the above example, I wanted to exclude f_someDate. That is, I wanted to validate all input components ( minus those that have the disabled attribute ) EXCEPT for f_someDate.
private void obtainChildren(UIComponent component, Set<String> allInputIds) {
     for (UIComponent childComponent : component.getChildren()) {
          if (childComponent instanceof UIInput || childComponent instanceof UICommand) {
               allInputIds.add( childComponent.getId() );
          }
           
          if (childComponent.getChildCount() > 0) {
               obtainChildren(childComponent, allInputIds);
          }
     }                    
}

public String includeAllExcept(String listOfIds) {
     StringTokenizer tokenizer = new StringTokenizer(listOfIds, " ");
     Set<String> allInputIds = new HashSet<String>();
     Set<String> inputIdsToExclude = new HashSet<String>();
     while( tokenizer.hasMoreTokens() ) {
          inputIdsToExclude.add(tokenizer.nextToken());
     }
     
     UIViewRoot root = FacesContext
          .getCurrentInstance()
          .getViewRoot();
     
     obtainChildren(root, allInputIds);
     allInputIds.removeAll(inputIdsToExclude);
     
     StringBuilder builder = new StringBuilder();
     for( String inputIdToExecute : allInputIds ) {
          builder.append(inputIdToExecute);
          builder.append(' ');
     }
     
     return builder.toString().trim();
}
  • 1. Re: EL expression for the render or execute attribute to exclude component ids
    gimbal2 Guru
    Currently Being Moderated
    Ah, the sharing of code and ideas. I used to do that years ago when I stumbled onto a WTF.

    But the fact of the matter is that your post is going to disappear off of the radar tomorrow and nobody performs research anymore (even if that is as simple as performing a Google search), so your effort was likely misspent. Better put this kind of stuff in a personal blog, not in a forum. If your work is in some way useful, people who know better will start to link to it in forum questions.
  • 2. Re: EL expression for the render or execute attribute to exclude component ids
    jmsjr Newbie
    Currently Being Moderated
    gimbal2 wrote:
    Ah, the sharing of code and ideas. I used to do that years ago when I stumbled onto a WTF.

    But the fact of the matter is that your post is going to disappear off of the radar tomorrow and nobody performs research anymore (even if that is as simple as performing a Google search), so your effort was likely misspent. Better put this kind of stuff in a personal blog, not in a forum. If your work is in some way useful, people who know better will start to link to it in forum questions.
    Well, I don't have and will probably never have a personal blog. Even if I do, I do believe that this forum will last longer than my personal blog, and no one will probably even look at my personal blog even if I had one ( Who am I in the world of JSF compared to BalusC, Ed Burns, and yourself ? ). Thus, the people here can comment, criticise, improve, or even reject the idea altogether.

    In any case, it was an idea where instead of specifying the components to execute / render via the execute and render attributes respectively, you actually want to say "execute / render all components ... EXCEPT these". Who knows, maybe someday we can have something like:
    <f:ajax ... execute="@form[except='componentA componentB']" ... />
    Of course, the above is not a valid syntax ...
    Seems like a reasonable ( and maybe common ?? ) thing that others would want to do.

    Edited by: jmsjr on 14-Jan-2013 21:52