1 2 Previous Next 15 Replies Latest reply on Jul 31, 2007 2:43 PM by pmuir

    selectManyCheckbox

    tompom

      I want to display a selectManyCheckbox where the checkboxes are preselected if there was a preceding selection (a selection is persisted).

      carBean.carList is a java.util.List of car objects (not of Strings):

      <h:selectManyCheckbox id="cars"
       value="#{carsBean.car}">
       <f:selectItems
       value="#{carBean.carList}"/>
      </h:selectManyCheckbox>


      How can I achieve that? Do I need a converter?

      Does anyone have a complete code sample?

        • 1. Re: selectManyCheckbox
          damianharvey

          The preselection is determined by the value of the property in the Bean - ie. if carsBean.car is a list of Cars then those that are present in that list will be 'pre-selected' in your selectManyCheckbox.

          You can use s:convertEntity but have a read of Chapter 28 of the Seam Reference manual first http://docs.jboss.com/seam/2.0.0.B1/reference/en/html/controls.html. You may also find s:selectItems easier than f:selectItems.

          <h:selectManyCheckbox id="cars" value="#{carsBean.car}">
           <f:selectItems value="#{carBean.carList}"/>
           <s:convertEntity/>
          </h:selectManyCheckbox>

          Cheers,

          Damian.

          • 2. Re: selectManyCheckbox
            junkie

            Thanks, actually this is the code I already have. It works fine, the only problem is that my checkboxes are not pre-selected with the current list status. It drives me crazy:

            <h:selectManyCheckbox value="#{client.paymentmethods}" required="true" layout="pageDirection">
             <s:convertEntity />
            
             <s:selectItems value="#{allPaymentMethods.resultList}"
             var="paymentMethod"
             label="#{msg[paymentMethod.code]}"/>
             <s:validate/>
            </h:selectManyCheckbox>


            "allPaymentMethods" is just an entity query in my components.xml.

            Any ideas?

            • 3. Re: selectManyCheckbox
              junkie

              Oh, and user "tompom" = "JUnkie" ;-)

              • 4. Re: selectManyCheckbox
                pmuir

                This does 'just work' - every value which .equals a selectItem value will be selected. Post client. And make sure that client.paymentmethods is returning the correct list.

                • 5. Re: selectManyCheckbox
                  junkie

                  Thanks Pete.

                  For me it works only "one way": My selection is saved correctly to the db. If I select a single item my console says:

                  17:10:08,551 INFO [STDOUT] Hibernate:
                   delete
                   from
                   clients_paymentmethods
                   where
                   clients_id=?
                  
                  17:10:08,551 INFO [STDOUT] Hibernate:
                   insert
                   into
                   clients_paymentmethods
                   (clients_id, paymentmethods_id)
                   values
                   (?, ?)


                  But a fresh call to the page that displays the selectManyCheckbox shows all the checkboxes unchecked, including the one that I selected and resides as a row in the db.

                  Pete: Could you please recommend a configuration to me? I'm using Seam 1.2.1.GA on JBoss AS 4.2. Should it work under this configuration?


                  --- Additional information ---

                  This is my web.xml:
                  <?xml version="1.0" encoding="UTF-8"?>
                  <web-app version="2.4"
                   xmlns="http://java.sun.com/xml/ns/j2ee"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
                  
                  
                   <!-- Seam -->
                  
                   <listener>
                   <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
                   </listener>
                  
                   <servlet>
                   <servlet-name>Seam Resource Servlet</servlet-name>
                   <servlet-class>org.jboss.seam.servlet.ResourceServlet</servlet-class>
                   </servlet>
                  
                   <servlet-mapping>
                   <servlet-name>Seam Resource Servlet</servlet-name>
                   <url-pattern>/seam/resource/*</url-pattern>
                   </servlet-mapping>
                  
                   <filter>
                   <filter-name>Seam Filter</filter-name>
                   <filter-class>org.jboss.seam.web.SeamFilter</filter-class>
                   </filter>
                  
                   <filter-mapping>
                   <filter-name>Seam Filter</filter-name>
                   <url-pattern>/*</url-pattern>
                   </filter-mapping>
                  
                   <!-- MyFaces -->
                   <!--
                   <listener>
                   <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
                   </listener>
                   -->
                  
                   <context-param>
                   <param-name>javax.faces.CONFIG_FILES</param-name>
                   <param-value>/WEB-INF/navigation.xml</param-value>
                   </context-param>
                  
                   <context-param>
                   <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
                   <param-value>client</param-value>
                   </context-param>
                  
                   <context-param>
                   <param-name>facelets.DEVELOPMENT</param-name>
                   <param-value>true</param-value>
                   </context-param>
                  
                   <context-param>
                   <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
                   <param-value>.xhtml</param-value>
                   </context-param>
                  
                   <servlet>
                   <servlet-name>Faces Servlet</servlet-name>
                   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
                   <load-on-startup>1</load-on-startup>
                   </servlet>
                  
                   <!-- Faces Servlet Mapping -->
                   <servlet-mapping>
                   <servlet-name>Faces Servlet</servlet-name>
                   <url-pattern>*.seam</url-pattern>
                   </servlet-mapping>
                  
                   <!-- Ajax4jsf setup -->
                  
                   <!-- ajax4jsf -->
                   <filter>
                   <display-name>Ajax4jsf Filter</display-name>
                   <filter-name>ajax4jsf</filter-name>
                   <filter-class>org.ajax4jsf.Filter</filter-class>
                   </filter>
                   <filter-mapping>
                   <filter-name>ajax4jsf</filter-name>
                   <url-pattern>*.seam</url-pattern>
                   </filter-mapping>
                  
                   <!-- Propagate conversations across redirects -->
                   <filter>
                   <filter-name>Seam Redirect Filter</filter-name>
                   <filter-class>org.jboss.seam.servlet.SeamRedirectFilter</filter-class>
                   </filter>
                   <filter-mapping>
                   <filter-name>Seam Redirect Filter</filter-name>
                   <url-pattern>*.seam</url-pattern>
                   </filter-mapping>
                  
                  
                  
                  </web-app>


                  This is my faces-config:
                  <faces-config version="1.2"
                   xmlns="http://java.sun.com/xml/ns/javaee"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
                  
                   <application>
                   <view-handler>org.jboss.seam.ui.facelet.SeamFaceletViewHandler</view-handler>
                   <el-resolver>org.jboss.seam.jsf.SeamELResolver</el-resolver>
                  
                   </application>
                  
                   <lifecycle>
                   <phase-listener>org.jboss.seam.jsf.SeamPhaseListener</phase-listener>
                   </lifecycle>
                  
                  </faces-config>


                  • 6. Re: selectManyCheckbox
                    pmuir

                    Well Seam 1.2.1.GA is targetted at JBoss AS 4.0.5.GA but I doubt this is the problem. So, put a breakpoint on the getter for client.paymentmethods and see whether the correct list is being returned. Don't just assume that because the data in the database, it is loaded correctly.

                    • 7. Re: selectManyCheckbox
                      junkie

                      Thanks again Pete.

                      I have made sure that Client.getPaymentmethods() is called and returns the correct list. It is called for each item in allPaymentMethods.resultList. So if there are three items in allPaymentMethods.resultList the following debug version of Client.getPaymentmethods() returns the output below if the Client has selected two PaymentMethods (MASTERCARD and VISA):

                      public List<PaymentMethod> getPaymentmethods() {
                       for (PaymentMethod p : paymentmethods){
                       System.out.println(p.getId() + " " + p.getCode());
                       }
                       return paymentmethods;
                      }



                      18:21:00,739 INFO [STDOUT] 1 MASTERCARD
                      18:21:00,739 INFO [STDOUT] 2 VISA
                      18:21:00,739 INFO [STDOUT] 1 MASTERCARD
                      18:21:00,739 INFO [STDOUT] 2 VISA
                      18:21:00,739 INFO [STDOUT] 1 MASTERCARD
                      18:21:00,739 INFO [STDOUT] 2 VISA

                      My checkboxes are just empty.

                      • 8. Re: selectManyCheckbox
                        pmuir

                        So you need to make sure that the item in the entity query .equals() the item in the selectXXX. If you are using conversation scope and SMPCs all the way, this just works, otherwise, try implementing and .equals method on the entity , break on it, and see what is going on.

                        • 9. Re: selectManyCheckbox
                          junkie

                          I have the same problem with all my other controls. Until now I only needed several <h:selectOneMenu> and could therefore work around the issue by just adding one single <f:selectItem> followed by <s:selectItems> as below. <f:selectItem> just works for me and pre-selects the last selection.

                          <h:selectOneMenu value="#{client.currency}" required="true">
                           <s:convertEntity />
                           <f:selectItem itemLabel="#{msg[client.currency.isocode]}" itemValue="#{client.currency}" />
                           <s:selectItems value="#{allCurrencies.resultList}"
                           var="currency"
                           label="#{msg[currency.isocode]}"/>
                           <s:validate/>
                          </h:selectOneMenu>


                          I have just seen your latest post. The allPaymentMethods.resultList is generated by a SMPC but I use a default PC in the action session bean. Good hint that I shouldn't mix them! Thanks again, I hope I can fix this issue that starts to get a real problem for me...

                          • 10. Re: selectManyCheckbox
                            junkie

                            I changed all my session beans to make use of a SMPC. Does not help, my checkboxes are still empty (same with all my drop down boxes if I don't work with f:selectItem).

                            I'll try the .equals() method.

                            • 11. YEAAAAAHHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!!!!
                              junkie

                              IT FINALLY WORKS!!!

                              I've just added equals() to my PaymentMethod entity like this:

                              public boolean equals(Object o){
                               PaymentMethod pm = (PaymentMethod)o;
                               if (pm.getId() == this.getId()){
                               return true;
                               }
                               return false;
                               }


                              Did the same thing for all my other entities and my other controls work without workaround now.

                              PETE: YOU ROCK!!

                              I can't really express how thankful I am for your help. This issue really drove me crazy. But it's soooo good to know to get good support for this great Seam framework and to see that it really works.

                              Again: Thank you very much for your help and your patience, Pete.

                              If you think you now know why I was running into the issue I would appreciate it if you could post it briefly. Might be very interesting for others, too.

                              tears of joy in my eyes :-)))

                              • 12. Re: selectManyCheckbox
                                junkie

                                This would be a safer and more generic equals() method that does not have to be changed for different entities.

                                public boolean equals(Object o){
                                return (o != null && (this.getClass().cast(o)).getId() == this.getId());
                                }

                                Have fun.

                                • 13. Re: selectManyCheckbox
                                  pmuir

                                  Yeah, I know the exact problem, in fact, its a oft discussed topic when using hibernate. There is something on the SeamProblemsFAQ about this (but not coming from your angle, I will update).

                                  When you load the same entity twice from the same persistence context the same object is returned. If you load the same entity from two different persistence contexts a different object is returned, so they don't have "object equality". So, if you load and select everything using the same PC you are home and dry not implementing .equals (look at the hibernate website for an in depth discussion of this, and why we don't recommend this), but if you don't...

                                  We should really document this much better as it comes up time and time again...

                                  • 14. Re: selectManyCheckbox
                                    junkie

                                    Thanks,

                                    that's very interesting as I thought the objects are equal although they come from different PCs, I thought they are just not "identical".

                                    Two different objects having the exact same state (same property values) can be considered as equal I thought. From that perspective my objects were "equal" before I overwrote equals().

                                    1 2 Previous Next