11 Replies Latest reply on Dec 2, 2011 1:46 PM by thorstenn

    a4j:ajax and multiple h:selectOneRadio elements

    thorstenn

      Hi all,

       

      I use several h:selectOneRadio buttons to build a more user friendly selection interface, something like this

      layout.gif

       

      Selection and rerender works fine until I start an ajax call with a commandLink element. The linkElement starts the persistence process to dbin my case.

      To avoid problems with logic steps behind I created a simple sample attached below. But same behaviour again.

      After debugging the process I figure out that if link is clicked the setter of the pos property is called with value 0. Only exception: The last element is selected.

       

      XHTML file

       

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

      <html xmlns="http://www.w3.org/1999/xhtml"

          xmlns:h="http://java.sun.com/jsf/html"

          xmlns:f="http://java.sun.com/jsf/core"

          xmlns:ui="http://java.sun.com/jsf/facelets"

          xmlns:a4j="http://richfaces.org/a4j"

          xmlns:rich="http://richfaces.org/rich">

       

      <f:view contentType="text/html">

          <h:head>

          </h:head>

          <h:body>

              <h:form>   

             

                  <rich:panel id="headerPanel">

                      <rich:tabPanel switchType="client">

                          <rich:tab header="Header">

                              <rich:panel>       

       

                                  <h:selectOneRadio value="#{bean.pos}">

                                      <f:selectItem itemValue="0" itemLabel="Top left" />

                                      <a4j:ajax event="click" render="headerPanel" />

                                  </h:selectOneRadio>

                                 

                                  <h:selectOneRadio value="#{bean.pos}">

                                      <f:selectItem itemValue="1" itemLabel="Top right" />

                                      <a4j:ajax event="click" render="headerPanel" />

                                  </h:selectOneRadio>

                                 

                                  <h:selectOneRadio value="#{bean.pos}">

                                      <f:selectItem itemValue="2" itemLabel="Center" />

                                      <a4j:ajax event="click" render="headerPanel" />

                                  </h:selectOneRadio>

                                 

                                  <h:selectOneRadio value="#{bean.pos}">

                                      <f:selectItem itemValue="3" itemLabel="Bottom left" />

                                      <a4j:ajax event="click" render="headerPanel" />

                                  </h:selectOneRadio>

                                 

                                  <h:selectOneRadio value="#{bean.pos}">

                                      <f:selectItem itemValue="4" itemLabel="Bottom right" />

                                      <a4j:ajax event="click"    render="headerPanel" />

                                  </h:selectOneRadio>

                                 

                              </rich:panel>       

                          </rich:tab>

                      </rich:tabPanel>

                  </rich:panel>

                 

                  <a4j:commandLink value="start ajax event" render="headerPanel" execute="headerPanel"/>

                 

              </h:form>

          </h:body>

      </f:view>

      </html>

       

      JAVA Bean

       

      import java.io.Serializable;

      import javax.faces.bean.ManagedBean;

      import javax.faces.bean.SessionScoped;

       

       

      @ManagedBean

      @SessionScoped

      public class Bean implements Serializable{

          private static final long serialVersionUID = -9194353440404794097L;

         

          private int pos;

       

          public int getPos() {

              return pos;

          }

       

          public void setPos(int pos) {

              System.out.println("set pos:" + this.pos + " -> to -> " + pos);

              this.pos = pos;

          }

      }

       

      Output if not last element is selected

       

      set pos:0 -> to -> 2 (1)

      set pos:2 -> to -> 0

      set pos:0 -> to -> 0

      set pos:0 -> to -> 2

      set pos:2 -> to -> 0

      set pos:0 -> to -> 0

       

      Output if last element is selected

       

      set pos:0 -> to -> 4

      set pos:4 -> to -> 0

      set pos:0 -> to -> 0

      set pos:0 -> to -> 0

      set pos:0 -> to -> 0

      set pos:0 -> to -> 4

       

       

      What I do

       

      Selected the third radio box (with value 2) and hit the link element. Why is the setter method called so often?

      I expected: First click on the radio box: (1), then hit the ajax link element, maybe an additional line in console but not 5 with two which resets my value back to 0 ... In addition I posted the result if I select the last radio box (value 4) and hit the link. Works fine but also printed more lines out as excepted by me.

       

       

      Environement information

       

      - JSF2 & Richfaces4 Milestone4

      - Apache Tomcat 7

      - JAVA 6

       

       

      Would be grateful for each hint.

       

      Thanks,

      Thorsten

       

      updated - added more detailed information

        • 1. Re: a4j:ajax and multiple h:selectOneRadio elements
          healeyb

          I think the defaut event is "valueChange", not "change", can you just omit the event= attribute and

          see if it improves things? A tragic clash of event names, it has to be said...

           

          Regards,

          Brendan.

          • 2. Re: a4j:ajax and multiple h:selectOneRadio elements
            thorstenn

            Thanks for your reply! Tried it but without an positive result :/

            • 3. Re: a4j:ajax and multiple h:selectOneRadio elements
              healeyb

              Hi, I'd not read the original post properly. You'll need to use execute= on the a4j:commandLink,

              specifying the selectOneRadio components either individually, or wrap them all in a panelGroup

              id="inputid", and specify execute="inputid". Hopefully this will help!

               

              Regards,

              Brendan.

              • 4. Re: a4j:ajax and multiple h:selectOneRadio elements
                healeyb

                Ah - now I see my mistake. I keep forgetting that a4j:commandButton default execute value

                is @form, which means that my previous suggestion is unlikely to help. Sorry.

                • 5. Re: a4j:ajax and multiple h:selectOneRadio elements
                  liuliu

                  1. i think event for selectoneradio is onclick

                   

                  2. there is no form in your example.

                  • 6. Re: a4j:ajax and multiple h:selectOneRadio elements
                    thorstenn

                    Thanks for your efforts guys!

                     

                    Seems that the fault is not that easy to find so I rewrote my start post. Or I missed something in my old post

                    I attached now a full XHTML file and the bean source code.

                     

                    In addition a more detailed debug information list.

                     

                    Hope this helps!

                    • 7. Re: a4j:ajax and multiple h:selectOneRadio elements
                      mcmurdosound

                      Setters been called is the default behavior and since all of your h:selectOneRadio elemets use the same valuebinding, they overwrite each other. The last one wins.

                       

                      You could try a valueChangeListener. Hmmm, no - the last one still wins.

                      1 of 1 people found this helpful
                      • 8. Re: a4j:ajax and multiple h:selectOneRadio elements
                        thorstenn

                        hi all,

                         

                        Today I had some time to try a little bit around in this behaviour and I found a working solution for my problem but I lack the why ...

                         

                        What I do: I surrounded my radio buttions by an additional forms h:form element. The result: If I push the button or play around in other parts of my main form nothing resets my buttons back to pos 0 or 4. The problem was as already stated one post above that all radio buttons call the change method and the last one wins.

                         

                        <h:form>                                   <-- form1

                             ...

                             Some elements

                             ...

                         

                             <h:form>                              <-- form2

                                  Radio Buttons

                             </h:form>

                         

                             CommandLink

                         

                        </h:form>

                         

                        What I get is that the h:form "extracts" the radio button region out of the rest of the page.

                        But why could I call rerender actions on elements of form1 out of form2? Because they are nested and it's possible to call elements from up (form2) to down (form1) but not the other way from down to up? Thanks for clary that!

                        • 9. Re: a4j:ajax and multiple h:selectOneRadio elements
                          mcmurdosound

                          Don't nest forms! It's forbidding in html - although jsf does not really render the nested form as an html form element, it usually causes a  lot of trouble.

                          1 of 1 people found this helpful
                          • 10. Re: a4j:ajax and multiple h:selectOneRadio elements
                            thorstenn

                            Oh... Thank you for your valuable hint.

                             

                            Yesterday I found an other way how to fix it, but it has a greater effort to implement it so I decided myself for the "form" one. The alternative solution is to change the execute property of all rich: ... /aj4: ... elements in the first form to execute="@this".

                             

                            Seems to be that I have to give it a second chance.

                            • 11. Re: a4j:ajax and multiple h:selectOneRadio elements
                              thorstenn

                              Back again ... with good news

                               

                              At first I removed my nested form element. After that I changed the execute property of all rich:/a4j: components to not invoke any of the radioButtons unless I want it. (E.g. I select one of the radio buttons). So I prevent the unwished call of the setter methods.

                               

                              Thanks all, problem solved!