4 Replies Latest reply on May 31, 2007 4:15 AM by mustaghattack

    Versatile component : component binding, facelets or new com

    mustaghattack

      Hi everyone,

      I'm writing a questionnaire maker app and I would need a versatile component which could render either a list/menu/checkbox/radio/text depending on type/style attribute.

      I see 3 solutions : component binding, facelets component or JSF component.
      Component binding is deprecated in the seam's doc. Facelets component doesnt seem appropriate (too much logic in the composition).
      So my last solution is to write a JSF component but it would be a pity to start from scratch since all the selectOne / many component are already existing.

      Is there anyone who see a nice way to achieve this ?
      Thanks
      Bruno

        • 1. Re: Versatile component : component binding, facelets or new
          matt.drees

          I'm doing something similar in my project.

          I use a few Facelets TagHandlers based on Rick Hightower's articles (http://www.ibm.com/developerworks/java/library/j-facelets2.html). My page looks something like this:

          <h:panelGrid id="questionPanel" columns="3">
          
           <crs:customQuestions
           registrationType="#{registrationType}"
           questionTextVar="questionText"
           questionNumberVar="i"
           requiredVar="required">
          
          
           <h:outputLabel for="answerInput#{i}" value="#{i}" id="questionNumber#{i}"/>
          
           <s:formattedText value="#{questionText}" id="questionText#{i}"/>
          
           <h:panelGroup>
           <s:decorate>
           <f:facet name="aroundInvalidField">
           <s:span styleClass="errors"/>
           </f:facet>
           <crs:isText>
           <h:inputText id="answerInput#{i}"
           value="#{registrationProcess.pageAnswers[i ].valueString}"
           required="#{required}">
           <a:support event="onblur" reRender="questionErrors#{i}"/>
           <crs:validateQuestion/>
           </h:inputText>
           </crs:isText>
          
           <crs:isDate>
           <h:inputText id="answerInput#{i}"
           value="#{registrationProcess.pageAnswers[i ].valueDate}"
           required="#{required}">
           <crs:validateQuestion/>
           <s:convertDateTime pattern="MM/dd/yyyy"/>
           <a:support event="onblur" reRender="questionErrors#{i}"/>
           </h:inputText>
           <s:selectDate for="answerInput#{i}">
           <h:graphicImage url="img/dtpick.gif" style="margin-left:5px"/>
           </s:selectDate>
           </crs:isDate>
          
           <crs:isBoolean>
           <h:selectBooleanCheckbox
           id="answerInput#{i}"
           value="#{registrationProcess.pageAnswers[i ].valueBoolean}"
           required="${required}">
           <crs:validateQuestion/>
           </h:selectBooleanCheckbox>
           </crs:isBoolean>
          
           <br clear="none"/>
           <a:outputPanel id="questionErrors#{i}">
           <s:message/>
           </a:outputPanel>
           </s:decorate>
           </h:panelGroup>
          
           </crs:customQuestions>
           </h:panelGrid>
          


          Note that I haven't updated this to use the newer s:decorate methodology, but you get the idea.

          • 2. Re: Versatile component : component binding, facelets or new
            mustaghattack

            Thanks for the reply. In this article Rick Hightower explain how to make compile-time tag, which doesn't work for my requirements.
            It's not difficult to turn them into render-time tags but I found easier to just use the rendered attribute.

            I've done a component which work like this :

            <rw:pollquestion answerType="#{q.answerType}"
             answerStyle="#{q.answerStyle}"
             answers="#{q.answers}"
             freeText="#{q.freeText}">
             <s:selectItems value="#{q.options}" var="opt" label="#{opt.text}"/>
            </rw:pollquestion>
            

            Type can be OPEN, MULTIPLE or SINGLE. Style is one of LIST, MENU, TICK_HORIZONTAL, TICK_VERTICAL. You get a list of POJO into answers if the type is not OPEN or a String in freeText.

            It works but it's a pain in the ass to write it. I finally decided to stick with facelets / rendered attribute.

            • 3. Re: Versatile component : component binding, facelets or new

              For dynamic components I use a component that builds it's tree in encodeBegin(). So for your example consult the relevant attributes and create the corresponding JSF component for list/menu/checkbox/radio/text.

              I've used this succesfully to build grids of dynamic properties where the type of each property determines the input control type.

              Cheers.

              Mike.

              • 4. Re: Versatile component : component binding, facelets or new
                mustaghattack

                Ok well I didn't try that one ... I thought that wasn't possible to add children during the render phase.
                I'll have a look,

                Thanks

                Bruno