2 Replies Latest reply on Oct 5, 2010 8:46 AM by carlhecker

    Seam noob: Categorized h:SelectManyCheckbox with s:selectItems

    carlhecker

      I have a Map of categories and lists of corresponding options.  I need to loop through the categories, and nested loop through the options, to display the information to the user. 
      So I'd like it to look like somewhat like this at the end of the day (I know I'm using a <ul> here but you get the point):


      <ul style="list-style-type: none;">
         <li>Category</li>
         <li><input type="checkbox">Option</li>
         <li><input type="checkbox">Option</li>
      
         <li>Category</li>
         <li><input type="checkbox">Option</li>
         <li><input type="checkbox">Option</li>
         <li><input type="checkbox">Option</li>
      </ul>



      <ui:repeat value="#{action.keys}" var="category">
             #{category}<br/>
             <h:selectManyCheckbox value="#{action.optionList}">
                <s:selectItems value="#{action.map[category]}"
                      var="option" label="#{option.description}" />
                <s:convertEntity />
             </h:selectManyCheckbox>
          </ui:repeat>
      </ul>




      • I'm having issues with this because when the form submits, it's only passing on the bottom <h:selectManyCheckbox> to persist (each selectmany is a new group).




      • When I move the <h:selectManyCheckbox> outside of the <ui:repeat> so it wraps everything, it won't allow me to use <s:convertEntity>.  Without the convertEntity, the selectItems isn't even rendered.




      • I've tried using <f:selectItem> but I still get trouble with <s:convertEntity> because it's not wrapped by the <h:selectManyCheckbox>.



      I feel like I must be missing something.  I've tried many combinations and nothing seems to be working.  Thanks for the help!

        • 1. Re: Seam noob: Categorized h:SelectManyCheckbox with s:selectItems
          njrich28

          Try putting a logging statement in your action.setOptionList() method. You'll probably find that it is called for each category - each time it's called it overwrites the values from the previous category the net effect being that it looks like only the last group works.


          That's because when Faces builds the component tree it'll build it with many selectManyCheckboxes linked to the same model value. During the update models phase of the request, faces will traverse the tree and call the action.setOptionList() method for each component.


          It's quite a tricky one to solve because you basically need a getter/setter for each list (not possible if the categories are dynamic) or you can store the lists in a map and get a consolidated view later.


          In your Action class:


              // key is category (presume it's a String) and value is List for each category
              private Map<String, List> optionMap;
          
              public Map<String, List> getOptionMap {
                  return optionMap;
              }
          
              public void setOptionMap(Map<String,List> optionMap) {
                  this.optionMap = optionMap;
              }
          
              public List getConsolidatedList() {
                  List consolidatedList = new ArrayList();
                  for (List optionList : optionMap.values()) {
                      consolidatedList.addAll(optionList);
                  }
                  return consolidatedList;
              }
              
          



          In your page:


          <ui:repeat value="#{action.keys}" var="category">
              #{category}<br/>
              <h:selectManyCheckbox value="#{action.optionMap[category]}">
                  <s:selectItems value="#{action.map[category]}"
                      var="option" label="#{option.description}" />
                  <s:convertEntity />
              </h:selectManyCheckbox>
          </ui:repeat>
          



          You may need to initialise the optionMap variable somehow but hopefully this should get you on your way.

          • 2. Re: Seam noob: Categorized h:SelectManyCheckbox with s:selectItems
            carlhecker

            Unfortunately, Seam doesn't seem to like


            <h:selectManyCheckbox value="#{action.optionMap[category]}">



            My categories aren't dynamic per se, but I wanted to code it so that if the database changed, the site would handle it appropriately.  I guess I'm going to have to hardcode this one.


            Thanks for the help!