title: Dynamically generate ice:commandButton components
body: <p>I've been trying a lot of different things that I would think would work like expected. However, they are causing me some frustration. Here's the scoop:</p>
  
  <p>I am using ICEFaces 1.8 components in a Java EE web application. My goal is to render a bunch of ice:commandButtons on the page based on a query to my database. I want these buttons to be able to toggle selections that I will later use for parameters to another query to the database (basically a query front end of sorts for a set of users). I would like the output to look like so:</p>
  
  <p><img src="https://3.bp.blogspot.com/_n_tMTNWlgdQ/SniHmmjWalI/AAAAAAAAAA4/xQDtx0y4P-Y/s320/deselected.PNG" alt="Deselected"></p>
  
  <p>When I click on a button, I would like the following update to my page:</p>
  
  <p><img src="https://1.bp.blogspot.com/_n_tMTNWlgdQ/SniHmRVhK2I/AAAAAAAAAAw/SSoOLEugUjc/s320/selected.PNG" alt="Selected"></p>
  
  <p>When I created the buttons on my page statically, as such:</p>
  
  <pre><code>&lt;ice:commandButton id="seasonSEP09" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2009-2010" /&gt;
  &lt;ice:commandButton id="seasonSEP08" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2008-2009" /&gt;
  &lt;ice:commandButton id="seasonSEP07" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2007-2008" /&gt;
  &lt;ice:commandButton id="seasonSEP06" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2006-2007" /&gt;
  </code></pre>
  
  <p>this works great, and each button works individually as I would expect. My backing bean is updated, the parameters are correctly added in updateSeasons() method, and my output at the end yields the correct records.</p>
  
  <p>However, I know this is not what I want. I don't want to update these anytime another season is entered in the system. Maintainance nightmare, right?</p>
  
  <p>So what I want to do is dynamically generate these ice:commandButton components based on my database table full of Season objects. Here is the Season class I am using:</p>
  
  <pre><code>public class Season
  {
      String StartMonth;
      String Season;
  
      public String getStartMonth()
      {
          return StartMonth;
      }
      public void setStartMonth(String startMonth)
      {
          StartMonth = sweep;
      }    
      public void setSeason(String season)
      {
          Season = season;
      }
      public String getSeason()
      {
          return Season;
      }
  }
  </code></pre>
  
  <p>Very straightforward. Two properties, which I'm guaranteed to be unique in the database. </p>
  
  <p>Here is the backing bean I am using:</p>
  
  <pre><code>public class Bean
  {
      public Bean()
      {
          defineSeasonsList();
      }
  
      public List&lt;HtmlCommandButton&gt; seasonsList;
  
      // seasonsList getter &amp; setter omitted
  
      public List&lt;String&gt; selectedSeasons;
  
      // selectedSeasons getter &amp; setter omitted
  
      private void defineSeasonsList()
      {
          seasonsList = new ArrayList&lt;HtmlCommandButton&gt;();
          selectedSeasons = new ArrayList&lt;String&gt;();
  
          try
          {
              hibernate.openTransaction();
  
              for(Season season:defineSeasonsListFromDataSource()))
              {
                  HtmlCommandButton button = new HtmlCommandButton();
  
                  button.setId("season" + season.getStartMonth());
                  button.setValue(season.getSeason);
                  button.setStyle("background-color: #FFFFFF;");
                  button.setPartialSubmit(true);
  
                  seasonsList.add(button);
              }                         
          } 
          catch (Exception e)
          {
              System.out.println("Error defining seasons list: " + e.getMessage());
          }
          finally
          {
              hibernate.commitTransaction();
          }               
      }
  
      public void updateSeasons(ActionEvent ae)
      {
          HtmlCommandButton selected = (HtmlCommandButton) ae.getComponent();
  
          if(selectedSeasons.contains(selected.getValue().toString()))
          {
              selectedSeasons.remove(selected.getValue().toString());   
              selected.setStyle("background: #FFFFFF;");
          }
          else
          {
              selectedSeasons.add(selected.getValue().toString());
              selected.setStyle("background: #009DD9; color: #FFFFFF;");
          }
      }
  }   
  </code></pre>
  
  <p>OK, so here comes my dilemma(s).</p>
  
  <p>First, I tried to render this markup: </p>
  
  <pre><code>&lt;p&gt;
      &lt;ice:panelGroup&gt;
          &lt;ice:panelSeries id="seasonsList" value="#{bean.seasonsList}" var="season"&gt;
                  &lt;ice:commandButton binding="#{season}"/&gt;                                        
          &lt;/ice:panelSeries&gt;
      &lt;/ice:panelGroup&gt;
  &lt;/p&gt;     
  </code></pre>
  
  <p>And I get this output:</p>
  
  <p><img src="https://2.bp.blogspot.com/_n_tMTNWlgdQ/SniLF7r4QbI/AAAAAAAAABA/pS7hhW-kB-I/s320/badButtons.PNG" alt="Bad Buttons"></p>
  
  <p>So, being frustrated and adventurous, I tried to render this markup to achieve my goal:</p>
  
  <pre><code>&lt;p&gt;
      &lt;ice:panelGroup&gt;
          &lt;ice:panelSeries id="seasonsList" value="#{bean.seasonsList}" var="season"&gt;
                  &lt;ice:commandButton id="#{season.id}" partialSubmit="true" style="background-color: #FFFFFF" value="#{season.value}" actionListener="#{bean.updateSeasons}"/&gt;                                        
          &lt;/ice:panelSeries&gt;
      &lt;/ice:panelGroup&gt;
  &lt;/p&gt;   
  </code></pre>
  
  <p>Which yielded the following stacktrace:</p>
  
  <p>Aug 4, 2009 2:28:11 PM com.sun.faces.lifecycle.Phase doPhase
  SEVERE: JSF1054: (Phase ID: RENDER_RESPONSE 6, View ID: /phase1.jspx) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@1a477b7]
  Aug 4, 2009 2:28:11 PM org.apache.catalina.core.StandardWrapperValve invoke
  SEVERE: Servlet.service() for servlet Persistent Faces Servlet threw exception
  java.lang.IllegalArgumentException: #{season.id}
      at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:549)
      at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:351)
      at javax.faces.webapp.UIComponentTag.createComponent(UIComponentTag.java:219)
      at javax.faces.webapp.UIComponentClassicTagBase.createChild(UIComponentClassicTagBase.java:486)
      at javax.faces.webapp.UIComponentClassicTagBase.findComponent(UIComponentClassicTagBase.java:670)
      at javax.faces.webapp.UIComponentClassicTagBase.doStartTag(UIComponentClassicTagBase.java:1142)
      at com.icesoft.faces.component.CommandButtonTag.doStartTag(CommandButtonTag.java:741)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:204)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229)
      at com.icesoft.faces.webapp.parser.Parser.parse(Parser.java:162)
      at com.icesoft.faces.application.D2DViewHandler.renderResponse(D2DViewHandler.java:464)
      at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:153)
      at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
      at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
      at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
      at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:17)
      at com.icesoft.faces.context.View$2$1.respond(View.java:47)
      at com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith(ServletRequestResponse.java:197)
      at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet$ThreadBlockingRequestResponse.respondWith(ThreadBlockingAdaptingServlet.java:36)
      at com.icesoft.faces.context.View$2.serve(View.java:72)
      at com.icesoft.faces.context.View.servePage(View.java:133)
      at com.icesoft.faces.webapp.http.core.SingleViewServer.service(SingleViewServer.java:52)
      at com.icesoft.faces.webapp.http.common.ServerProxy.service(ServerProxy.java:11)
      at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet$4.service(MainSessionBoundServlet.java:114)
      at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
      at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet.service(MainSessionBoundServlet.java:160)
      at com.icesoft.faces.webapp.http.servlet.SessionDispatcher$1.service(SessionDispatcher.java:42)
      at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet.service(ThreadBlockingAdaptingServlet.java:19)
      at com.icesoft.faces.webapp.http.servlet.EnvironmentAdaptingServlet.service(EnvironmentAdaptingServlet.java:63)
      at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:62)
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
      at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:153)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Thread.java:619)</p>
  
  <p>Am I trying to do something that I shouldn't be doing?</p>
  
  <p>Is there a better way to accomplish this goal?</p>
  
  <p>If more information is necessary I'd be happy to provide it.</p>
  
  <p>Thanks in advance, my friends.</p>
  
  <p><strong>UPDATE</strong>:</p>
  
  <p>So I tried changing the seasonsList collection from List to List and rendering some different markup, like so:</p>
  
  <pre><code>&lt;p&gt;
      &lt;ice:panelGroup&gt;
          &lt;ice:panelSeries value="#{bean.seasonsList}" var="season"&gt;
                  &lt;ice:commandButton partialSubmit="true" style="background-color: #FFFFFF" value="#{season}" actionListener="#{Phase1EventBean.updateSeasons}"/&gt;                                        
          &lt;/ice:panelSeries&gt;
      &lt;/ice:panelGroup&gt;
  &lt;/p&gt;
  </code></pre>
  
  <p>And changing the defineSeasonsList() method to:</p>
  
  <pre><code>public void defineNationalSeasonsList()
  {
      try
      {
          seasonsList = new ArrayList&lt;String&gt;();
          selectedSeasonsList = new ArrayList&lt;String&gt;();
  
          hibernate.openTransaction();
  
          for(UedaNationalDates season:hibernate.getList(new UedaNationalDates(), QueryFactory.getUedaNationalSeasons(hibernate.getHibSession())))
          { 
              nationalSeasonsList.add(season.getSeason());
          }       
      } 
      catch (Exception e)
      {
          System.out.println("Error defining nationalMeasurementPeriods: " + e.getMessage());
      }
      finally
      {
          hibernate.commitTransaction();
      }               
  }
  </code></pre>
  
  <p>This actually renders all the buttons I would like to see, and adds them correctly to the selectedSeasonsList in my backing bean when I click on them, and removes them from it when I click again.</p>
  
  <p>However, on the UI, <strong>every</strong> button appears to be toggled when I click just the one button. For example, when I click on 2009-2010, this is what I see:</p>
  
  <p><img src="https://3.bp.blogspot.com/_n_tMTNWlgdQ/Sni7R9BR2BI/AAAAAAAAABI/unU4vxlm_xk/s320/allSelected.PNG" alt="All Selected"></p>