11 Replies Latest reply on Nov 11, 2010 9:47 AM by Tony Tony

    Dynamic generate richfaces controls in a datatable

    Tony Tony Newbie

      Ok, I'll try to explain my problem.

       

      I have a rich:datatable, which  renders rows based on a datatype. One column of the datatable depends on one property of that datatype (ControlType property). Depending on that field, I have to render a combobox, or a textbox, or a checkbox list, or a grid, in that column.

       

      I think I need to create that controls programatically (create UIPanel, UIComboBox, UITextBox, etc). I Created a panel in my .xhtml and bind it to a UIPanel in the backing bean. There I can place personalized controls inside my panel, but the getter of that property in the backing bean fires just one time during page load and doesnt fire for each row.

       

      <rich:panel binding="#{viewForm.panelRes}" >                           
      </rich:panel>

       

      public UIPanel getPanelRes() {

           if (bindColumnGroup.isRowAvailable()) {
                  Question l_quest = (Question) bindColumnGroup.getRowData();
                  panelRes = new HtmlPanel();
                  UIComponent c;
                  if (l_quest.getType() == ControlType.COMBO)
                  {
                      c = new HtmlComboBox();
                      panelRes.getChildren().add(c);
                  }
                  else
                  {
                      if (l_quest.getType() == ControlType.TEXT)
                      {
                          c= new HtmlInputText();
                          panelRes.getChildren().add(c);
                      }               
                  }   

                     ///////        etc, etc, etc (More controls
            }

           return panelRes;

             
          }
            

       

       

      Hoy can I achieve that? Help!!

       

      (Sorry my bad english)

        • 1. Re: Dynamic generate richfaces controls in a datatable
          Kriya Studio Newbie

          I think you have to loop every row in the datatable, and for each row find out what type of control it needs to creat. if it only fires in one row, might be because it create the objet for that particular row, and doesn't create the subsequence objects in the other rows.

          • 2. Re: Dynamic generate richfaces controls in a datatable
            Ilya Shaikovsky Master

            in similar situation we used:

             

            ui:include src="#{controller.control}"

             

            and rendered one of the needed include src's according to type. That include should contain input/command needed. Also you could pass required params to that include.

            1 of 1 people found this helpful
            • 3. Re: Dynamic generate richfaces controls in a datatable
              Tony Tony Newbie

              Mmmm,,, Can you be more specific? Iterate how, where?

              Iterate in the backing bean? Triggered by what event?

               

              When I run my code, I can see the dynamically created panel in all rows, but I want to get the content of it dependant of the specific row properties.

              Thank you

              • 4. Re: Dynamic generate richfaces controls in a datatable
                Tony Tony Newbie

                Thank you Ilya Shaikovsky. I will try what you are saying tomorrow. I am not sure about this, I will probably post more questions.

                What exactly is "controller.control"?.  Are you telling me to have lots of "ui:include" (one for each control type) and render just the one I need (choosing with "rendered" attribute).

                 

                Thank you!

                • 5. Re: Dynamic generate richfaces controls in a datatable
                  Ilya Shaikovsky Master

                  There was case constructed like:

                  <columns>

                       <include="#{tableVar[columnVar].dataType}">

                            <ui:param value="#{tableVar[columnVar].value}"/>

                       </include>

                  </columns>

                   

                  and if for example the some column was required to input/output data - calendar controls was added: because dataType for the object was initialized with something like "/includes/richtags/calendar.xhtml"(page which contained just rich:cakendar with value from param). For other control type - other control view id was returned.

                  1 of 1 people found this helpful
                  • 6. Re: Dynamic generate richfaces controls in a datatable
                    Tony Tony Newbie

                    I am almost there Ilya, but still having problems. I am getting the following error:

                    javax.el.ELException: Could not Resolve Variable [Overflow]: msj
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:64)
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:60)
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:60)
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:60)
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:60)

                                    .

                                    .

                            Caused by: java.lang.StackOverflowError
                         at java.lang.String.<init>(Unknown Source)
                         at java.lang.StringBuffer.toString(Unknown Source)
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:64)
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:60)
                         at com.sun.facelets.el.VariableMapperWrapper.resolveVariable(VariableMapperWrapper.java:60)

                                    .

                                    .

                     

                    My include code is the following:

                     

                    <ui:include src="#{question.controlXhtml}"  />

                     

                    being "question" my var in the datatable. controlXhtml returns a String. i.e. it returns "/backend/TextBox.xhtml"

                    and TextBox.xhtml is the following:

                    <?xml version="1.0" encoding="ISO-8859-1" ?>

                     

                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

                    <html xmlns="http://www.w3.org/1999/xhtml"
                        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:ui="http://java.sun.com/jsf/facelets">
                    <ui:component>
                        <h:form>
                            <h:inputText />
                        </h:form>
                    </ui:component>
                    </html>

                    • 7. Re: Dynamic generate richfaces controls in a datatable
                      Ilya Shaikovsky Master

                      doh... missed that problem.. there are problem that iteration var can't be resolved when include processed. It's content added to view during build view phase and var of dataTable accessible only in iteration durin render responce. read more

                       

                      In my case it worked because was done inside forEach and not inside UIData.

                       

                      So in order that to start work with data table condition should be inside include and not in include src. I could propose to try something like:

                       

                      <ui:include src="/includes/tableControls">

                           <ui:param value="#{question.controlType}" name="controlType"/>

                           <ui:param value="#{question.answer}" name="value"/>

                      <ui:include>

                       

                      and include:

                      <ui:component xmlns="http://www.w3.org/1999/xhtml"
                          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:ui="http://java.sun.com/jsf/facelets">
                                <h:inputText  value="#{value}" rendered=" 'INPUT'==#{controlType} "/>

                                <h:selectOne value="#{value}" rendered=" 'S_ONE'==#{controlType} "/>

                                <h:selectMany value="#{value}" rendered=" 'S_MANY'==#{controlType} "/>
                      </ui:component>

                      • 8. Re: Dynamic generate richfaces controls in a datatable
                        Tony Tony Newbie

                        Thank you for the last answer.

                        The rendered attribute is still not working.

                        In my included page I have.

                         

                        <h:inputText renderered="'enum_controlType_text' == #{controlType.text}" />
                        <h:selectOneMenu renderered="'enum_controlType_selectone' == #{controlType.text}" />

                         

                        ControlType is an enum with a getText() method. It is returning correctly the expected text, since I added a <h:outputText value="#{controlType.text}"/> for debugging purposes and it displayed the correct text for each question. But the rendered condition is not working because it is rendering both controls. Shoud I use String.equal? Can I use that in Expression Language? how?

                        • 9. Re: Dynamic generate richfaces controls in a datatable
                          Tony Tony Newbie

                          I also tried using directly the Enum and not the text property.

                          i.e.

                          <h:inputText renderered=" 'TEXT' == #{controlType}" />
                          <h:selectOneMenu renderered=" 'COMBO' == #{controlType}" />

                           

                          It is still rendering both controls....

                          There are no exceptions in the console.....

                          • 10. Re: Dynamic generate richfaces controls in a datatable
                            Tony Tony Newbie

                            Sorry! It is rendered and not "renderered" heheheh

                            Now none of the controls are being rendered

                            rendered attribute is returning false in both cases....

                            • 11. Re: Dynamic generate richfaces controls in a datatable
                              Tony Tony Newbie

                              I solved it adding to my Enum some boolean properties to use in the rendered attribute.

                               

                              The following code is in my Enum:

                              public enum ControlType {

                                   COMBO, TEXT;

                               

                              public boolean isText() {
                                      return this == ControlType.TEXT;
                                  }
                                 
                                  public boolean isCombo() {
                                      return this == ControlType.COMBO;
                                  }

                              }

                               

                              This in my included page (TableControls.xhtml):

                              <?xml version="1.0" encoding="ISO-8859-1" ?>

                               

                              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

                               

                              <html xmlns="http://www.w3.org/1999/xhtml"
                                  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:ui="http://java.sun.com/jsf/facelets">
                              <ui:component>
                                  <h:form>   
                                  <h:inputText rendered="#{controlType.text}" />
                                  <h:selectOneMenu rendered="#{controlType.combo}" />
                                 
                                  </h:form>
                              </ui:component>
                              </html>

                               

                               

                              And this inside my datatable code in the main page:

                              <ui:include src="/backend/TableControls.xhtml"  >
                                            <ui:param value="#{question.type}" name="controlType"/>
                              </ui:include> 

                               

                               

                              I dont know why comparing strings in the rendered attribute didn't work but it doesn't matter now.

                              I now will add more control types and complete functionality.

                               

                              Thank you Ilya.