3 Replies Latest reply on Sep 18, 2008 11:39 AM by lseymore

    Dynamic decoration, template bound to EL expression

    lseymore
      Hi,

      I'm trying to select the template for a ui:decoration / s:descoration dynamically by using an EL expression. 

      My aim is to create an editor based on the object that is bounded to that template.  If it is a boolean then a checkbox should be used, if it is a string a textbox should be used etc...

      I've added some snippets below to demonstrate what i'm trying to do.

      main.xhtml
      Assume obj exists somewhere in the page's scope.
      <s:decorate template="#{seamHelper.getEditor(obj)}">
        <ui:param name="binding" value="#{obj}"/>
      </s:decorate>

      ...

      SeamHelper.java
      @Name()
      public class SeamHelper {
      public String getEditor(Object obj) {
          if (obj instanceof java.lang.String) {
            return "/editors/stringEditor.xhtml";
          } // if
         
          if (obj instanceof java.lang.Boolean) {
            return "/editors/booleanEditor.xhtml";
          } // if
         
          return "/editors/noSuchEditor.xhtml";
        }
      }

      ...

      booleanEditor.xhtml
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
        xmlns:c="http://java.sun.com/jstl/core"
        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:rich="http://richfaces.org/rich">
        <!--
        java.lang.Boolean
        -->
        <h:selectBooleanCheckbox value="#{binding}"/>
      </ui:composition>

      I just can't get this to work and seam errors such as the following occur:
      main.xhtml: Could not instantiate Seam component: processHome

      When I remove the template expression and replace it with an actual string everything works ok.

      Any comments please?

      Thanks,
      - L
        • 1. Re: Dynamic decoration, template bound to EL expression
          sjmenden

          You might have to do some extra digging on this one, I don't know off hand.  The template attribute is defined as a TagAttribute in the DecorateHandler in facelets which the getValue looks like:


          /**
               * If literal, then return our value, otherwise delegate to getObject,
               * passing String.class.
               *
               * @see #getObject(FaceletContext, Class)
               * @param ctx
               *            FaceletContext to use
               * @return String value of this attribute
               */
              public String getValue(FaceletContext ctx) {
                  if (this.literal) {
                      return this.value;
                  } else {
                      return (String) this.getObject(ctx, String.class);
                  }
              }



          so, if it is not a literal, Facelets treats it as a ValueExpression.  So, from all appearances both "/editors/booleanEditor.xhtml" and #{seamHelper.getEditor(obj)}" should evaluate to the same String when the DecorateHandler tag invokes:



          ctx.includeFacelet(parent, this.template.getValue(ctx));




          I may be missing something, so I'd suggest joining the Facelets user mailing list, and posting there, they are quite responsive.

          • 2. Re: Dynamic decoration, template bound to EL expression
            lseymore

            Thanks for your input Samuel, I believe you're on the right track here...

            • 3. Re: Dynamic decoration, template bound to EL expression
              lseymore
              Hi,

              I have resolved the error.  Its my own fault for not reading the stack traces and not understanding Seam conversations well enough yet.

              Tested the following:
              <c:set var="obj" value="#{true}"/>
              <ui:decorate template="#{seamHelper.getEditor(obj)}">
                <ui:param name="binding" value="#{obj}"/>
              </ui:decorate>
              Checkboxes where generated...

              <c:set var="obj" value="#{'Some string'}"/>
              <ui:decorate template="#{seamHelper.getEditor(obj)}">
              <ui:param name="binding" value="#{obj}"/>
              </ui:decorate>
              Textboxes where generated...

              At least now everyone can use this concept to create generic editors ;)

              Regards,
              -L