8 Replies Latest reply on Jan 18, 2010 2:16 PM by Jan Gurda

    Passing a parameter into a template ?

    Craig Horrell Newbie
      Is it possible to pass a parameter from a <s:decorate> tag into it's template?

      I want to reuse a template, but have a different class for a <div> tag depending on usage.

      Thanks,
      Craig.
        • 1. Re: Passing a parameter into a template ?
          blabno Master

          Of course it is possible :


          s:decorate :


                             <s:decorate id="nameField" template="/layout/edit.xhtml">
                                  <ui:define name="label">#{messages['person.firstname']}</ui:define>
                                  <h:inputText id="name" required="true" value="#{personHome.instance.firstname}">
                                      <a:support event="onblur" reRender="nameField" ajaxSingle="true"/>
                                  </h:inputText>
                                  <ui:define name="jojo">hahaha</ui:define>
                              </s:decorate>



          template :


          <ui:composition 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:s="http://jboss.com/products/seam/taglib">
          
              <div class="prop">
          
          
                  <ui:insert name="jojo"/>
                  
          
                  <s:label styleClass="name #{invalid?'errors':''}">
                      <ui:insert name="label"/>
                      <s:span styleClass="required" rendered="#{required}">*</s:span>
                  </s:label>
          
                  <span class="value #{invalid?'errors':''}">
                      <s:validateAll>
                          <ui:insert/>
                      </s:validateAll>
                  </span>
          
                  <span class="error">
                      <h:graphicImage value="/img/error.gif" rendered="#{invalid}" styleClass="errors"/>
                      <s:message styleClass="errors"/>
                  </span>
                  
              </div>
          
          </ui:composition>

          • 2. Re: Passing a parameter into a template ?
            Frank Upgang Newbie
            <ui:param name="xyz" value="something" /> works, too.

            Here's an example defining a style class via parameter.

            <ui:composition>
                <div class="#{styleClass}">
                    [...]               
                </div>
            </ui:composition>

            <s:decorate template="someTemplate.xhtml">
                <ui:param name="styleClass" value="fancy" />
                [...]
            </s:decorate>
            • 3. Re: Passing a parameter into a template ?
              Craig Horrell Newbie
              <blockquote>
              _Frank Upgang wrote on Oct 01, 2009 12:13:_<br/>

              <ui:param name="xyz" value="something" /> works, too.

              Here's an example defining a style class via parameter.

              <ui:composition>
                  <div class="#{styleClass}">
                      [...]               
                  </div>
              </ui:composition>

              <s:decorate template="someTemplate.xhtml">
                  <ui:param name="styleClass" value="fancy" />
                  [...]
              </s:decorate>
              </blockquote>

              Thanks for this. It worked. I did this to make the style optional with a default:

                <div class="#{labelClass == null ? 'label' : labelClass}">


              • 4. Re: Passing a parameter into a template ?
                Craig Horrell Newbie






                _Frank Upgang wrote on Oct 01, 2009 12:13:_<br/>
                
                <ui:param name="xyz" value="something" /> works, too.
                
                Here's an example defining a style class via parameter.
                
                <ui:composition>
                    <div class="#{styleClass}">
                        [...]                
                    </div>
                </ui:composition>
                
                <s:decorate template="someTemplate.xhtml">
                    <ui:param name="styleClass" value="fancy" />
                    [...]
                </s:decorate>
                







                Thanks for this. It worked. I did this to make the style optional with a default:




                  <div class="#{labelClass == null ? 'label' : labelClass}">




                • 5. Re: Passing a parameter into a template ?
                  Matthias Preier Newbie

                  Hi there,


                  this method is just perfect for most of my issues. You can now insert params to tag attributes! How cool is this? But I have some problems whith a special case of that method.


                  I use the decorater with some traditional defines and a param to to pass an action method to an action attribute in the template.


                  <s:decorate template="/layout/panel-delete.xhtml">
                       <ui:define name="header">...</ui:define>
                       <ui:define name="message">...</ui:define>
                       <ui:param name="deleteAction" value="#{contentHome.remove}" />
                  </s:decorate>



                  And here is the importent part of the template.


                  <a4j:commandButton value="delete" styleClass="button-remove"
                       ajaxSingle="true" action="#{deleteAction}"
                       oncomplete="if (#{facesContext.maximumSeverity == null}) #{rich:component('panelDelete')}.hide();"
                       reRender="listForm" />



                  The generated HTML code for the button looks pretty good, but when I try to click the button, I get an exception.




                  ...
                  Caused by: javax.faces.el.EvaluationException: javax.el.PropertyNotFoundException: /layout/panel-delete.xhtml @48,28 action="#{deleteAction}": /view/content-list.xhtml @97,65 value="#{contentHome.remove}": Property 'remove' not found on type com.mgsoftech.seminarverwaltung.session.home.ContentHome_$$_javassist_seam_3
                       at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:84)
                       at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91)
                       ... 51 more
                  Caused by: javax.el.PropertyNotFoundException: /layout/panel-delete.xhtml @48,28 action="#{deleteAction}": /view/content-list.xhtml @97,65 value="#{contentHome.remove}": Property 'remove' not found on type com.mgsoftech.seminarverwaltung.session.home.ContentHome_$$_javassist_seam_3
                       at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:70)
                       at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:77)
                       ... 52 more



                  How is this possible, contentHome should be a normal entityHome and if I hard code the action method in the template it won't occure?!?


                  Thanks,
                  Matthias.

                  • 6. Re: Passing a parameter into a template ?
                    blabno Master

                    The problem is that action gets evaluated when it is passed to template (i guess its that way).
                    You should do something like this:


                    <ui:param name="deleteAction" value="#{elHelper.createMethodExpression('contentHome.remove')}" />



                    cause your function should return method binding (since it is not value binding; if it was value binding you could have done it your way) in order to pass it as param in facelet.


                    @Scope(ScopeType.STATELESS)
                    @Name("elHelper")
                    public class ELHelper {
                    
                        @In
                        private Expressions expressions;
                    
                        public MethodExpression createMethodExpression(String expression) {
                            return expressions.createMethodExpression(expression).toUnifiedMethodExpression();
                        }
                    }

                    • 7. Re: Passing a parameter into a template ?
                      Matthias Preier Newbie

                      Hmm I already thought that something like this could be the problem.


                      I tested your solution and the helper method gets called when the page is rendered and after I clicked the button, but the remove method never gets invoked!
                      There are no exceptions and no other messages, my panel just hides without doing anithing. :(


                      Any suggestions what the problem could be or how I could find the problem.


                      Thanks.


                      PS: I know that I can bypass this problem by passing the whole button to the template, but it would be much easier to handle by using params.

                      • 8. Re: Passing a parameter into a template ?
                        Jan Gurda Newbie

                        Matthias Preier wrote on Nov 26, 2009 15:01:


                        <s:decorate template="/layout/panel-delete.xhtml">
                             <ui:define name="header">...</ui:define>
                             <ui:define name="message">...</ui:define>
                             <ui:param name="deleteAction" value="#{contentHome.remove}" />
                        </s:decorate>



                        And here is the importent part of the template.

                        <a4j:commandButton value="delete" styleClass="button-remove"
                             ajaxSingle="true" action="#{deleteAction}"
                             oncomplete="if (#{facesContext.maximumSeverity == null}) #{rich:component('panelDelete')}.hide();"
                             reRender="listForm" />





                        Hi,


                        I think it would be better:


                        <s:decorate template="/layout/panel-delete.xhtml">
                             <ui:define name="header">...</ui:define>
                             <ui:define name="message">...</ui:define>
                             <ui:param name="deleteBean" value="#{contentHome}" />
                                <ui:param name="deleteMethod" value="remove" />
                        </s:decorate>
                        
                        
                        <a4j:commandButton value="delete" styleClass="button-remove"
                             ajaxSingle="true" action="#{deleteBean[deleteMethod]}"
                             oncomplete="if (#{facesContext.maximumSeverity == null}) #{rich:component('panelDelete')}.hide();"
                             reRender="listForm" />
                        



                        Here is topic about it: http://seamframework.org/Community/DynamicActionName