7 Replies Latest reply on May 11, 2007 2:02 PM by Charles Crouch

    programmatically apply a template to UIDecorate?

    Charles Crouch Expert

      Looking at the docs here http://docs.jboss.com/seam/1.2.1.GA/reference/en/html/validation.html

      I see reference to the cool feature of being able to use a template with the s:decorate tag.

       <s:decorate id="zipDecoration" template="edit.xhtml">
       <ui:define name="label">Zip code:</ui:define>
       <h:inputText id="zip" value="#{location.zip}" required="true">
       <a:support event="onblur" reRender="zipDecoration"/>
       </h:inputText>
       </s:decorate>


      However I'm currently programmatically creating the decorate components (org.jboss.seam.ui.UIDecorate) and then binding them into the page. The trouble is that I don't see any way to specify a template on the latest UIDecorate class?

      http://fisheye.jboss.com/browse/~raw,r=1.15/JBoss/jboss-seam/src/ui/org/jboss/seam/ui/UIDecorate.java

      I've got a growing suspicion thats this is going to be impossible :-(. But it would be *so* cool if you could :-)

      Thanks

        • 1. Re: programmatically apply a template to UIDecorate?
          Pete Muir Master

          Look at org.jboss.seam.ui.tag.DecorateHandler

          • 2. Re: programmatically apply a template to UIDecorate?
            Charles Crouch Expert

             

            "petemuir" wrote:
            Look at org.jboss.seam.ui.tag.DecorateHandler


            Okay, what am I looking for? Pardon my JSF ignorance but I presume you are implying that what I was hoping to do is not possible?

            Thanks

            • 3. Re: programmatically apply a template to UIDecorate?
              Pete Muir Master

              Sorry, I meant, thats where the magic is happening... You would need to build a similar handler to do this programmatically. I did a similar thing for Christian for the wiki a while back. I did blog about the general ideas, rather than the impl:

              http://pmuir.bleepbleep.org.uk/2007/04/building-plugin-system-in-facelets.html

              So, it all depends on how you are adding the UIDecorate to the tree at the moment...

              Post some code :p

              • 4. Re: programmatically apply a template to UIDecorate?
                Charles Crouch Expert

                 

                "petemuir" wrote:
                I did a similar thing for Christian for the wiki a while back.

                Cool, Christian and I briefly spoke on this topic when he was doing the wiki stuff. I think we had approximately similar requirements.
                Can you point me at the code you did?

                "petemuir" wrote:

                So, it all depends on how you are adding the UIDecorate to the tree at the moment...

                Post some code :p


                So its pretty simple stuff right now. We're creating a HtmlPanelGrid then for each form element (textbox, textarea etc) we want to render we create a UIDecorate

                UIDecorate component = (UIDecorate) getApplication().createComponent(UIDecorate.COMPONENT_TYPE);
                component.setId(getUniqueId());


                then add all the components relevant to that element as children of the UIDecorate
                decorator.getChildren().add(getUnescapedOutputText("<br/>"));
                decorator.getChildren().add(getTextAreaInputWidget());
                etc


                Then add the decorator back into the grid

                panelGrid.getChildren().add(decorator);


                Finally we outject the panelGrid and display it in a facelets page.

                <h:panelGrid binding="#{dynamicPanelGridTest}" />


                Hope this helps
                Cheers

                • 5. Re: programmatically apply a template to UIDecorate?
                  Christian Bauer Master

                  Check examples/wiki/ and the source in the .ui package.

                  • 6. Re: programmatically apply a template to UIDecorate?
                    Pete Muir Master

                    I would suggest not doing this via binding, but via a facelets component handler - it's harder to understand, but plays with the JSF lifecycle much better afaics. The work is done by faceletContext.includeFacelet("/path/to/facelet.xhtml") , but facelets is quite fragile as to how use this call (without components getting pruned from the tree).

                    • 7. Re: programmatically apply a template to UIDecorate?
                      Charles Crouch Expert

                      Ok, so let me just try and repeat back what I understand your sugestion to be:

                      Instead of using binding:

                      <h:panelGrid binding="#{dynamicPanelGridTest}" />

                      I would create my own tag handler, extending MetaTagHandler it looks like, and that in the page would go:

                      <myTag:renderForm formDefinition="#{myFormSchema}"/>


                      This tag handler implementation would then get the reference to the myFormSchema which lists what form elements should be included on the form. It would then iterate over this list calling ctx.includeFacelet(parent, faceletURL) appropriately for each form element, e.g. pseudo code...

                      ctx.includeFacelet(parent, /include/formTextComponent.xhtml);
                      ctx.includeFacelet(parent, /include/formRadioComponent.xhtml);
                      ctx.includeFacelet(parent, /include/formTextComponent.xhtml);

                      So how would I tell it each time I include a facelets page to use a different set of param's? e.g. duplicating this...

                       <ui:include src="/include/formTextComponent.xhtml">
                       <ui:param name="label" value="#{label1}"/>
                       <ui:param name="beanValue" value="#{value1}"/>
                       </ui:include>
                      
                       <ui:include src="/include/formRadioComponent.xhtml">
                       <ui:param name="label" value="#{label2}"/>
                       <ui:param name="beanValue" value="#{value2}"/>
                       <ui:param name="itemValues" value="#{listValues}"/>
                       </ui:include>
                      
                       <ui:include src="/include/formTextComponent.xhtml">
                       <ui:param name="label" value="#{label3}"/>
                       <ui:param name="beanValue" value="#{value3}"/>
                       </ui:include>
                      


                      Thanks