6 Replies Latest reply on Oct 11, 2013 1:08 PM by Brian Leathem

    strange excpetion when using c:foreach, rich:column and composite componennt

    liumin hu Master

      Hi,

      I met a strange exception when using RF4 way to build rich:columns, here is an example to produce the exception.

       

      page.xhtml for test page, input.xhml is for composite component, the  id for input must be there , and backing bean TestBean.java

       

      when you click on the button creat2columns, then click on creat5columns, you get the exception in exception.txt

       

      please help me

       

      thanks in advance

       

      ps : cant use the editor to format the code correctly.

        • 1. Re: strange excpetion when using c:foreach, rich:column and composite componennt
          liumin hu Master

          It is not a richfaces problem, replace the rich:datatable and rich:column with h:datatable and h:column still have the same exception.

          • 2. Re: strange excpetion when using c:foreach, rich:column and composite componennt
            Brian Leathem Master

            Can you paste your code samples into this thread (using the forums syntax highlighting?)  That'll make it easier for folks to scan through your code and offer comments/suggestions.

            • 3. Re: Re: strange excpetion when using c:foreach, rich:column and composite componennt
              liumin hu Master

              hi,

               

              I tried yestoday, but I cant do it correctly. The editor adds some extra tables when i paste the code, some xhtml is shown out of the block etc. So i put them in the attachements.

               

              I do it again, you can see the resultt is a disaster. i put a screen shot of what i see in the attachment.

               

              page.xhtml

               

              <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
                    xmlns:f="http://java.sun.com/jsf/core" xmlns:a4j="http://richfaces.org/a4j" xmlns:c="http://java.sun.com/jsp/jstl/core"
                    xmlns:my="http://java.sun.com/jsf/composite/my" xmlns:rich="http://richfaces.org/rich">
              <h:head>
              </h:head>
              <h:body>
                  <f:view>
                      <h:form>
                          <a4j:commandButton value="2 columns" action="#{testBean.creat2Headers()}" render="@form" />
                          <a4j:commandButton value="5 columns" action="#{testBean.creat5Headers()}" render="@form" />
                          <a4j:outputPanel id="patientMain" layout="block">
                              <rich:dataTable id="produitTable" var="produit" value="#{testBean.table}">
                                  <c:forEach items="#{testBean.header}" var="header">
                                      <rich:column>
                                          <my:input valueSelected="#{testBean.testValue}" />
                                      </rich:column>
                                  </c:forEach>
                              </rich:dataTable>
                              test
                              <my:input valueSelected="#{testBean.testValue}" />
                          </a4j:outputPanel>
                      </h:form>
                  </f:view>
              </h:body>
              </html>
              
              

               

              input.xhtml

               

              <?xml version="1.0" encoding="ISO-8859-1" ?>
              <html xmlns="http://www.w3.org/1999/xhtml" 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:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich"
                    xmlns:composite="http://java.sun.com/jsf/composite">
              <composite:interface>
                  <composite:attribute name="valueSelected" required="true"/>
              </composite:interface>
              <composite:implementation>
                  <h:inputText value="#{cc.attrs.valueSelected}" id="input"/>
              </composite:implementation>
              </html>
              
              

               

              TestBean.java

               

              @ManagedBean
              @ViewScoped
              public class TestBean implements Serializable{
              
                private List<String> table = new ArrayList<String>();
                private List<String> header=new ArrayList<String>();
                private Integer testValue=0;
              
                public TestBean(){
                logger.info("bean created");
                this.table.add("ligne1");
                this.header.add("header1");
                this.header.add("header2");
                }
              
                public void creat2Headers(){
                this.header.clear();
                this.header.add("header1");
                this.header.add("header2");
                }
              
                public void creat5Headers(){
                this.header.clear();
                this.header.add("header1");
                this.header.add("header2");
                this.header.add("header3");
                this.header.add("header4");
                this.header.add("header5");
                }
                
                 public List<String> getTable() {
                return this.table;
                }
              
                public void setTable(List<String> _table) {
                this.table = _table;
                }
              
                public List<String> getHeader() {
                return this.header;
                }
              
                public void setHeader(List<String> _header) {
                this.header = _header;
                }
              
                public Integer getTestValue() {
                return this.testValue;
                }
              
                public void setTestValue(Integer _testValue) {
                this.testValue = _testValue;
                }
              }
              

               

              exception:

               

              09/10 14:21:44,638 Grave [javax.enterprise.resource.webcontainer.jsf.application] JSF1007 : ID de composant j_idt4-j_idt88-input en double dans la vue.
              09/10 14:21:44,639 Grave [javax.enterprise.resource.webcontainer.jsf.application] +id: j_id1
              type: javax.faces.component.UIViewRoot@1aa3683
                +id: javax_faces_location_HEAD
                type: com.sun.faces.component.ComponentResourceContainer@4720c8
                  +id: __rf_skinning_resource
                  type: javax.faces.component.UIOutput@1b9692f
                  +id: j_id10
                  type: javax.faces.component.UIOutput@1a8b79a
                  +id: j_id11
                  type: javax.faces.component.UIOutput@1adf8ee
                  +id: j_id12
                  type: javax.faces.component.UIOutput@b1efde
                  +id: j_id13
                  type: javax.faces.component.UIOutput@1fae583
                +id: j_idt1
                type: <html xmlns="http://www.w3.org/1999/xhtml">
              
              
                +id: j_idt2
                type: javax.faces.component.UIOutput@1e0e0a5
                +id: j_idt70
                type: javax.faces.component.html.HtmlBody@bc9373
                  +id: j_idt4
                  type: javax.faces.component.html.HtmlForm@7494a2
                    +id: j_idt71
                    type: org.richfaces.component.UICommandButton@1ca5783
                    +id: j_idt72
                    type: org.richfaces.component.UICommandButton@1377f4e
                    +id: patientMain
                    type: org.richfaces.component.UIOutputPanel@86db88
                      +id: produitTable
                      type: org.richfaces.component.UIDataTable@1b6d69b
                        +id: j_idt84
                        type: org.richfaces.component.UIColumn@c38e48
                          +id: j_idt85
                          type: javax.faces.component.UINamingContainer@b23d43
                            +id: j_id3
                            type: javax.faces.component.UIPanel@f207c1
                              +id: input
                              type: javax.faces.component.html.HtmlInputText@1d42318
                        +id: j_idt86
                        type: org.richfaces.component.UIColumn@4c30e2
                          +id: j_idt87
                          type: javax.faces.component.UINamingContainer@1d6b89
                            +id: j_id3
                            type: javax.faces.component.UIPanel@1db3d85
                              +id: input
                              type: javax.faces.component.html.HtmlInputText@17f1876
                      +id: j_idt7
                      type:
                      tt
              
              
                      +id: j_idt88
                      type: javax.faces.component.UINamingContainer@d09913
                        +id: j_id3
                        type: javax.faces.component.UIPanel@a42543
                          +id: input  <===============
                          type: javax.faces.component.html.HtmlInputText@f1be33
                          +id: input  <===============
                          type: javax.faces.component.html.HtmlInputText@830cc6
                +id: j_idt63
                type: </html>
              
              
              • 4. Re: Re: strange excpetion when using c:foreach, rich:column and composite componennt
                Brian Leathem Master

                The problem comes about with the timing of the evaluation of the JSTL tags during the JSF lifecycle.  The JSTL tags are evaluated at the time the component tree is built during the RESTORE_VIEW phase, whereas your button action is executed in the INVOKE_APPLICATION phase.

                 

                Because of this timing issue, JSTL tags should be used for building static repeating components.  They are very effective in this use case, as they allow one to tailor the size of the component tree (as opposed to having a component tree filled with un-rendered compoennts).

                 

                The correct approach to dynamic repeating components is to use the a4j:repeat component, as this is evaluated at the time the page is rendered.  This is supported in the tab, accordion and toggle panels in richfaces, but is not yet supported for the table/column components.  See: https://issues.jboss.org/browse/RF-7882.

                 

                You might be able to workaround this by having your mthod that loops over the number of columns look for a request parameter (which is accessible directly during the RESTORE_VIEW phase) that defines the number of columns to create.

                • 5. Re: Re: strange excpetion when using c:foreach, rich:column and composite componennt
                  liumin hu Master

                  hi,

                   

                  I am sorry for my english, I dont understand your workaround. Do you mean c:foreach looks for a request paramter for number of columns?

                   

                  There is another thing i dont understand, it is the exceptions is thrown when creating the component who is NOT IN the foreach loop. And this example works , if i remove the id in the composite component OR remove the last composite component OR use a component other than the composite component. looking at the view generated, it creats twice the input component in the last composite component. why?

                   

                  Could you tell me how to creat those block with synthax highlignting?

                   

                  thanks

                  • 6. Re: Re: Re: strange excpetion when using c:foreach, rich:column and composite componennt
                    Brian Leathem Master

                    liumin hu wrote:

                     

                    I am sorry for my english, I dont understand your workaround. Do you mean c:foreach looks for a request paramter for number of columns?

                     

                    I was suggesting you create a JSF Phase Listener (or a system event listener) that can look for the request parameter early on in the JSF lifecycle and create the additional columns.  The more I think about it though, this likely won't work, as mutating the component might break subsequent JSF processes.

                     

                    liumin hu wrote:

                     

                    There is another thing i dont understand, it is the exceptions is thrown when creating the component who is NOT IN the foreach loop. And this example works , if i remove the id in the composite component OR remove the last composite component OR use a component other than the composite component. looking at the view generated, it creats twice the input component in the last composite component. why?

                     

                     

                    Try sticking a debugger on it, and following through the post-back lifecycle, checking when your various listeners are invoked.  If you have trouble interpreting the results, feel free to ask here for further clarification.

                     

                    liumin hu wrote:

                     

                    Could you tell me how to creat those block with synthax highlignting?

                     

                     

                    Click the ">>" in in the editor toolbar and choose "syntax highlighting".  You may have click the "advanced editor" link to get that icon in your toolbar.