13 Replies Latest reply on Jun 18, 2009 11:16 PM by jguglielmin

    h:selectOneListbox selection after postback

    ericjung2

      Hi,


      I have two dependent selectOneListboxes on a page. When the selection is changed in listbox countries, the options in listbox cities successfully changes. However, the selected option in listbox cities is always the first item in the list.


      The following code always selects the first item in the list after postback:


      <h:selectOneListbox id="city" value="#{service.selectedCity}" size="1" immediate="true">
        <s:selectItems value="#{service.cities}" var="city" label="#{city.description}"/>
        <s:convertEntity/>
      </h:selectOneListbox>



      but I want the selection to change when the value of this other listbox countries changes:


      <h:selectOneListbox id="country" value="#{service.selectedCountry}" size="1" immediate="true" valueChangeListener="#{service.countryChanged}" onchange="this.form.submit()">
        <s:selectItems value="#{findAllCountries}" var="country"  label="#{country.description}"/>
        <s:convertEntity/>
      </h:selectOneListbox>



      The ValueChange listener successfully populate


      public void countryChanged(ValueChangeEvent evt) {     
        if (evt.getNewValue() != null) {
          selectedCountry = (Country) evt.getNewValue();
          prepare(true);
        }
      FacesContext.getCurrentInstance().renderResponse();
      }



      Everything is in conversation scope. All entities override equals() and hashcode(), and use a primary key for equivalence checks. Please help!


      Thank you,
      Eric

        • 1. Re: h:selectOneListbox selection after postback
          nickarls

          Do you have messages tags to catch validation errors just in case? Can you see the equals/hashcode being hit when run in a debugger? Why the explicit renderResponse?

          • 2. Re: h:selectOneListbox selection after postback
            ericjung2

            Hi Nicklas,


            Thanks for the reply. Yes, I do have h:message tags to display validation errors. But I am using immediate="true" on both selectOneListboxes (not really sure if this is necessary), and the explicit renderResponse() is there to again ensure validation is bypassed. I'm not really sure if any of this is necessary.


            Yes, I do see equals() being called.


            Any other ideas? The list of cities does change correctly, but the selection is the problem (it should be selecting a different value besides the 0th item).


            Note that the prepare(true) method in the countryChanged() value change listener is what re-populates the list of cities.


            Eric

            • 3. Re: h:selectOneListbox selection after postback
              ericjung2

              I removed the explicit renderReponse and the immediate="true" on the cities listbox. Now I can see the underlying error, but I'm not sure how to fix it:




              java.lang.ClassCastException: com.foo.bar.City cannot be cast to java.lang.String
                   at com.icesoft.faces.renderkit.dom_html_basic.DomBasicInputRenderer.getConvertedValue(DomBasicInputRenderer.java:97)
                   at com.icesoft.faces.renderkit.dom_html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:122)
                   at javax.faces.component.UIInput.getConvertedValue(UIInput.java:936)
                   at javax.faces.component.UIInput.validate(UIInput.java:861)
                   at javax.faces.component.UIInput.executeValidate(UIInput.java:1071)
                   Truncated. see log file for complete stacktrace



              The City entity is really simple. Why can't it be converted to a String? Who's trying to do this conversion, is it s:convertEntity?

              • 4. Re: h:selectOneListbox selection after postback
                jguglielmin

                The whole idea of using <s:convertEntity/> is to actually select the id of the object in the list (vs a string).  Is this not what you want?  You would just have to then convert it back to the id if you wanted the entity anyways.  (you may very well have a valid use-case, just that you may want to use this as it is intended so will give you an example).
                 


                You definitely don't want immediate set to true as this bypasses the updateModel phase and so you won't be setting any value in your backing bean, but partialSubmit set to true will automatically populate whatever value/entity you have set in el for the selectOneListbox component once an item is selected from the list. (just use the setter).


                For some reason, I often get formatting errors when I try to include code on this forum, but if you want further help or examplex, you can always try the ICEfaces forum.

                • 5. Re: h:selectOneListbox selection after postback
                  jguglielmin

                  I should have worded that differently as the actual selection with that tag selects the entity (Country) and then you can set the id to a string attribute in your backing bean in the setter and use it for page parameters,etc. (it's what I meant.  hopefully that didn't confuse more than help).

                  • 6. Re: h:selectOneListbox selection after postback
                    jguglielmin

                    Suggested :-


                    <ice:selectOneListbox id="country" value="#{service.selectedCountry}"size="10" 
                                       partialSubmit="true">
                         <s:selectItems value="#{findAllCountries}" var="country"  label="#
                                       {country.description}" />
                         <s:convertEntity />
                    </ice:selectOneListbox>


                    You can use this inside the decorator template that comes with seam-gen for editing.  Any further logic can be placed inside the setSelectedCountry(Country c) method in the service bean.

                    • 7. Re: h:selectOneListbox selection after postback
                      ericjung2

                      Hi Judy,


                      Thanks for the replies. Your suggested code:


                      <ice:selectOneListbox id="country" value="#{service.selectedCountry}"size="10" partialSubmit="true">  <s:selectItems value="#{findAllCountries}" var="country" label="# {country.description}" />  <s:convertEntity /> </ice:selectOneListbox>



                      doesn't have a value change listener, so there's no way for me to update the list of cities when the country is changed. Also, you have size=10, not size=1, not sure why.



                      Does anyone know why I get:


                      java.lang.ClassCastException: com.foo.bar.City cannot be cast to java.lang.String




                      <s:convertEntity/>
                      is not the culprit; if I remove it, the same exception persists (but anyway, I do want to use <s:convertEntity/> because Country and City are both entities).


                      Thank you,


                      Eric

                      • 8. Re: h:selectOneListbox selection after postback
                        zhangxiubo
                        Perhaps because the immediate="true" makes the value bypass the entity converter, so you get String by calling evt.getNewValue().
                        • 9. Re: h:selectOneListbox selection after postback
                          jguglielmin

                          If you have ICEfaces-1.8.1, then you may want to look at <ice:setEventPhas> component.  I should have read your initial post more closely (still you don't want immediate="true").  There is an example showing exactly what you are looking for (country list selection changing the list of cities that populate the second list selection).  The seam-comp-showcase-1.8.1 sample app also shows this. 

                          • 10. Re: h:selectOneListbox selection after postback
                            ericjung2

                            Hi Judy,


                            I only see 1.8.0 at http://www.icefaces.org/main/downloads/detail.iface. Are you sure there is a 1.8.1?


                            Thanks,
                            Eric

                            • 11. Re: h:selectOneListbox selection after postback
                              jguglielmin

                              That's strange and I'll look into it.  1.8.0 version does have this component/example in it as well though.

                              • 12. Re: h:selectOneListbox selection after postback
                                ericjung2

                                Judy,


                                I found it in the source distribution. The example uses multi-select boxes (ice:selectManyListbox). Selection works well with ice:selectManyListbox. But I cannot get it to work with ice:selectOneListbox.


                                Any thoughts?


                                Eric

                                • 13. Re: h:selectOneListbox selection after postback
                                  jguglielmin

                                  Actually, the example uses a selectOneListbox for country (which is what you would want, correct?), then you would just change the city selection from a selectMany to selectOne, is that what you are referring to?