4 Replies Latest reply on Feb 29, 2008 7:55 AM by pete007

    How to validate if a ui:define variable equals a given string

      Hello, I am trying to create a menu on top of my page with a submenu on the left side.
      It is done all with image-links because the app will be called from touchscreen terminals,
      but I replaced the long link and image tags be only the filenames, so do not wonder.
      Also the menu lenghts are shrinked to 2 respectively 1 for better understanding.


      I already realized the structure, but I am not able to render the submenu depending
      on the current main menu entry and so it is with the highlighting of selected elements.
      This is really driving me crazy. So here is my code, maybe someone can give some hints?


      This is one of the pages which use my menu stuff:


      <!DOCTYPE ... >
      <ui:composition xmlns...
                      template="layout/template.xhtml">
        <ui:define name="mainmenu">staff</ui:define>
        <ui:define name="submenu">byname</ui:define>  
        <ui:define name="content">CONTENT OF STAFF_BY_NAME</ui:define>
      </ui:composition>



      Here is the template that renders the all pages:


      <!DOCTYPE ... >
      <html xmlns ... >
        <body>
          <table class="mainlayout">
            <tr><td colspan="2">header.png</td></tr>
            <ui:include src="mainmenu.xhtml"/>
            <tr><td colspan="2"><table>
              <tr><td><ui:include src="submenu.xhtml"/></td><td><ui:insert name="content"/></td></tr>
            </table></td></tr>
            <tr><td colspan="2">footer.png</td></tr>
          </table>
        </body>
      </html>



      This is the mainmenu.xhtml, it should use either the default or highlighted image.


      <tr xmlns ... >
        <td rendered="#{mainmenu=='staff'}">mainmenu_staff_default.png</td>
        <td rendered="#{mainmenu!='staff'}">mainmenu_staff_highlight.png</td>
        <td rendered="#{mainmenu=='rooms'}">mainmenu_rooms_default.png</td>
        <td rendered="#{mainmenu!='rooms'}">mainmenu_rooms_highlight.png></td>
      </tr>



      And finally the submenu.xhtml, should show only entries depending on the current value of the mainmenu.


      <table xmlns ... >
        <tr rendered="#{mainmenu=='rooms' and submenu=='byname'}"><td>submenu_rooms_byname_default.png</td></tr>
        <tr rendered="#{mainmenu=='rooms' and submenu!='byname'}"><td>submenu_rooms_byname_highlight.png</td></tr>
        ...
        <tr rendered="#{mainmenu=='staff' and submenu=='byname'}"><td>submenu_staff_byname_default.png</td></tr>
        <tr rendered="#{mainmenu=='staff' and submenu!='byname'}"><td>submenu_staff_byname_highlight.png</td></tr>
        ...
      </table>



      I wrote should because it does not do it. Instead all images of all menues appear on the display at the same time.


      I think, it has todo with the string comparison, but I cannot figure out, how it should be done correctly.
      I also tried #{main.equals('staff')} but I get the same result.


      Or can it be, that the parameters from the page file do not get to the menu-files?? Do I have to refresh them in the template-file? How can this be done?


      And shouldn't one of the two evaluations give true and one false anyway?


      All types of help are welcome, Pete

        • 1. Re: How to validate if a ui:define variable equals a given string

          After putting all into template.xhtml still all rendered parameters get evaluated to true.


          Now I am again at the rendered problem I had in the evening:
          ProblemWith..RenderedAttribute


          So, how can I pass a value to the template which then can be used in a expression for the rendered-attribute.


          Here is a simple example showing the problem, just forget the stuff above:


          <!DOCTYPE ... >
          <ui:composition xmlns...
                          template="layout/template.xhtml">
            <ui:define name="somename">somevalue</ui:define>
          </ui:composition>



          And here is a small template.xhtml:


          <!DOCTYPE ... >
          <html xmlns ... >
            <body>
              <table>
                <tr><td>A - always</td></tr>
                <tr rendered="someexpression1"><td>B - when true</td></tr>
                <tr rendered="someexpression2"><td>C - when false</td></tr>
              </table>
            </body>
          </html>



          To make it short, what do I have to insert for somename, somevalue, someexpression1 and someexperssion2 to see the rows A and B or A and C depending on the parameter??


          Thanks in advance, Pete

          • 2. Re: How to validate if a ui:define variable equals a given string
            keithnaas

            To pass simple strings to <ui:compositions/>, <ui:includes/>, etc., use <ui:param/>.  For complex html markup, use <ui:define/>  .


            Jacob Hookum, Mr. Facelets himself has a nice articleexplaining how to use those tags for templating.


            As for, the tr tags with rendered attributes, that will only work if you use jsfc.  I've never used it though.


            Try using an <h:dataTable/> with <h:columns/> instead.  Or an <h:panelGrid/>.  Or if you want a snazzy looking menu, you could use richfaces dropDownMenu

            • 3. Re: How to validate if a ui:define variable equals a given string
              keithnaas

              Oh and I forgot you could also go with wrapping the <tr/> with <s:fragment/>


              such as

              <s:fragment rendered="#{a == 'something'}">
                 <tr><td></td></tr>
              </s:fragment>
              

              • 4. Re: How to validate if a ui:define variable equals a given string

                Wow, really cool, you saved my day! ;)


                The jsfc I didn't understand how to use in my case so I took the fragment-way, and it worked immediately, thanks very much. It is very good to see, that my code was nearly correct, only that <tr>s and <td>s cannot get the rendered attribute.


                Thank you and have a nice day, Pete