7 Replies Latest reply on Sep 16, 2009 3:55 PM by gilad bar orion

    IllegalArgumentException with <f:attribute name="id" ...>

    Anthony Ogier Newbie

      Hello,


      I want to create a template to use with <ui:decorate .../> and I want the ability of setting a <ui:param name="id" .../> to it.


      So I created an specialSelectOneMenu.xhtml file containing :


      <h:selectOneMenu disabled="#{disabled}" value="#{value}" styleClass="#{listStyleClass}">
        <c:if test="#{not empty id}">
          <f:attribute name="id" value="#{id}"/>
        </c:if>
      </h:selectOneMenu>



      and I call it for exemple with :


      <ui:decorate template="specialSelectOneMenu.xhtml">
        <ui:param name="id" value="select1"/>
      </ui:decorate>



      The problem si that when my id parameter is defined (like here), I've got that stack :


      GRAVE: Error Rendering View[/pages/testSpecialOneMenu.xhtml]
      java.lang.IllegalArgumentException
              at javax.faces.component.UIComponent.setValueExpression(UIComponent.java:238)



      I've checked the source of (jsf-api-1.2_04-p02) javax.faces.component.UIComponent.setValueExpression(UIComponent.java:238)


          public void setValueExpression(String name, ValueExpression binding) {
      
              if (name == null) {
                  throw new NullPointerException();
              } else if ("id".equals(name) || "parent".equals(name)) {
                  throw new IllegalArgumentException();
              }



      Should I conclude that it is impossible to redefine the "id" of a component using the <f:attribute/> ?
      Or perhaps there is an other mean to do what I want... Do anyone has an other idea ?

        • 1. Re: IllegalArgumentException with <f:attribute name="id" ...>
          Daniel Hinojosa Master

          I got it to work by merely using:


           <h:outputText id="#{param.id}" value="Some value"/>
          

          • 2. Re: IllegalArgumentException with <f:attribute name="id" ...>
            Anthony Ogier Newbie

            Perhaps I didn't well explain my problem.


            Actually, I want to set an id only when I give a <ui:param name="id" value="..."/> to my template.
            That's because if I write my template like <h:selectOneMenu id="#{id}" ...> and that my id param is null or empty, then I have another exception, I don't remember which one.
            You can have this exception with your code if you don't send any id HTTP parameter I think...

            • 3. Re: IllegalArgumentException with <f:attribute name="id" ...>
              Daniel Hinojosa Master

              Well, I got this to work, and I hope this is what you are looking for...


              Smells.xhtml  (Couldn't think of a better name ;))


              <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                              xmlns:s="http://jboss.com/products/seam/taglib"
                              xmlns:ui="http://java.sun.com/jsf/facelets"
                              xmlns:f="http://java.sun.com/jsf/core"
                              xmlns:h="http://java.sun.com/jsf/html"
                              xmlns:t="http://myfaces.apache.org/tomahawk"
                              xmlns:rich="http://richfaces.org/rich"
                              template="layout/template.xhtml">
              
                  <ui:define name="main">
                      <h:form>
                          This is the main form
                          <ui:include src="smellychild.xhtml">
                                 <ui:param name="child_id" value="rock"/>
                          </ui:include>
                      </h:form>
                  </ui:define>
              </ui:composition>
              



              and the subform smellychild.xhtml (I love children, really I do)


              <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                              xmlns:s="http://jboss.com/products/seam/taglib"
                              xmlns:ui="http://java.sun.com/jsf/facelets"
                              xmlns:f="http://java.sun.com/jsf/core"
                              xmlns:h="http://java.sun.com/jsf/html"
                              xmlns:t="http://myfaces.apache.org/tomahawk"
                              xmlns:rich="http://richfaces.org/rich">
              
              
                  <h:outputText id="#{!empty child_id ? child_id : 'jazz'}" value="Rocken Roll"/>
              </ui:composition>
              

              • 4. Re: IllegalArgumentException with <f:attribute name="id" ...>
                Anthony Ogier Newbie

                I already tried that, but the problem is that as it's a template I'm creating, I can use it multiple times in a page.
                And if there are multiple id "jazz" in a single page, then there is a JSF error.


                So perhaps if someone know how to call the API which generate the id of components which don't define that attribute... it could be used in the previous code by replacing the child_id : 'jazz' with child_id : the_call_to_the_api.

                • 5. Re: IllegalArgumentException with <f:attribute name="id" ...>
                  Daniel Hinojosa Master

                  Hmmm, well you can do a child_id : the_call_to_the_api


                  I tried it out and got this...


                  <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                  <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                                  xmlns:s="http://jboss.com/products/seam/taglib"
                                  xmlns:ui="http://java.sun.com/jsf/facelets"
                                  xmlns:f="http://java.sun.com/jsf/core"
                                  xmlns:h="http://java.sun.com/jsf/html"
                                  xmlns:t="http://myfaces.apache.org/tomahawk"
                                  xmlns:rich="http://richfaces.org/rich"
                                  xmlns:a="https://ajax4jsf.dev.java.net/ajax"
                                  template="layout/template.xhtml">
                  
                      <ui:define name="main">
                          <h:form>
                              This is the main form
                              <ui:include src="smellychild.xhtml">
                                  <ui:param name="child_id" value="child_#{myBean.nextId}"/>
                              </ui:include>
                              <ui:include src="smellychild.xhtml">
                                  <ui:param name="child_id" value="child_#{myBean.nextId}"/>
                              </ui:include>
                              <ui:include src="smellychild.xhtml">
                                  <ui:param name="child_id" value="child_#{myBean.nextId}"/>
                              </ui:include>
                              <a:repeat value="#{myBean.actionFigures}" var="actionFigure" rowKeyVar="keyVar">
                                  <ui:include src="smellychild.xhtml">
                                      <ui:param name="child_id" value="child_#{keyVar}"/>
                                  </ui:include>
                              </a:repeat>
                          </h:form>
                      </ui:define>
                  </ui:composition>
                  



                  The first three includes are calls to the API. The last one is using the rich faces repeat and I am name the child_id based on a repeat collection of data.


                  • 6. Re: IllegalArgumentException with <f:attribute name="id" ...>
                    Daniel Hinojosa Master

                    WOW, what is wrong with my english...


                    haha. The last sentence should read


                    The last one uses the rich faces repeat and I name the child_id based on a repeat collection of data.


                    • 7. Re: IllegalArgumentException with <f:attribute name="id" ...>
                      gilad bar orion Newbie

                      I suspect the above solution creates a new 'nextId' every time.
                      better use

                       id="#{empty id ? facesContext.viewRoot.createUniqueId() : id
                       


                      thanks to Stephen Friedrich, see http://markmail.org/message/fcet77emso47xtk5