5 Replies Latest reply on Jun 22, 2009 9:39 AM by Nikos Paraskevopoulos

    submit button unable to trigger the action

    dan liu Newbie

      Hi,
      I am new to seam, and you help is really appreciated.


      I have a simpel wizard using page flow. The Next button(h:commandbutton) on the first page is disabled when the page is first time rendered. When user select the proper choice, the javascript enable the Next button. When clicks the Next button, the transition to second page does not happen. If I click the Next button one more time, then the transition occurs as specified in the page flow file.


      If I enable the Next button when the page is first time rendered, then the Next button transition occurs with no problem.


      Is this related to the disabled Next button? Or what might be wrong?

        • 1. Re: submit button unable to trigger the action
          Nikos Paraskevopoulos Novice

          Hi.


          If I understand right, this is a JSF question: You have a <h:commandButton disabled="#{condition}">. You evaluate the #{condition} in the client and enable the button at the client side; then, nothing happens the first time you press it, although it appears enabled. However, after the first submission, it works fine.


          The reason is that when the server-side JSF mechanism renders the component, it remembers its state. The disabled status, is part of the remembered state. When the server receives the first submission, it knows that the <h:commandButton> is disabled, so it doesn't evaluate its action. But it evaluates the #{condition}, which enables the component for the next submission.


          You need to make the server aware of the data changes that made the #{condition} to change value. If you are using RichFaces, the <a:support> will help you. Example:


          <h:inputText value="#{some.number}">
            <a:support event="onchange" reRender="next" />
          </h:inputText>
          
          <h:commandButon id="next" value="Next" disabled="#{some.number == null || some.number == 0}" />
          



          The <a:support> will let the server know of changes in the numerical value and re-render the button accordingly, after correctly setting its disabled status.

          • 2. Re: submit button unable to trigger the action
            dan liu Newbie

            Thank you very much for the nice and clean explaination.


            My first page contain 6 checkbox(using h:selectManyCheckbox) that user has to select all of them before go to the Next page.


            I did not use the a:support so that the ajax call does not make to server for each click.


            I tried to enable the Next botton at server side during update model phase, when the form is submitted(user clicks the Next button).


            As the update model phase occurs before the invoke application phase, I thought the sever should pick up the fact now the Next button is enabled, and evaluate the action and direct to next page. But this does not happen. The pages still action as descripted in my last post.


            What might be wrong?


            Thanks /dan


             

            • 3. Re: submit button unable to trigger the action
              dan liu Newbie

              Hi,


              I just noticed that in the update model phase when user clicks the next button, the Next button is enabled (System.out.println(a.isDisabled()) below returns false). It seems server knows the button is enabled even it is enabled from the server side.


              The question is: since button is enabled at updatemodel faces, why it is not picked up by the page flow?


              
                public void setSelectedItems(List<String> selectedItems) {
                      this.selectedItems = selectedItems;
                                     final FacesContext facesCtx = FacesContext.getCurrentInstance();      
                      final UIViewRoot root = facesCtx.getViewRoot();
              
                      root.invokeOnComponent(facesCtx, restrictions:next, new ContextCallback() {
                               public void invokeContextCallback(FacesContext context,
                                   UIComponent component) {
                                       HtmlCommandButton a =((HtmlCommandButton)component);
                                     log.info(a.isDisabled()); //this returns false
                                      // ((HtmlCommandButton)component).setDisabled(false);
                                                               
                               }                      
              
                              });
                  }
              



              • 4. Re: submit button unable to trigger the action
                dan liu Newbie

                sorry for the typo.
                I mean:


                It seems server knows the button is enabled even it is enabled from the CLIENT side.

                • 5. Re: submit button unable to trigger the action
                  Nikos Paraskevopoulos Novice

                  Hello again,


                  The standard action components (buttons and links) decide whether they were clicked during the Apply Request Values phase (see decode() methods in the relevant components and renderers). This phase occurs before the Update Model phase, so JSF does not have the chance to update the model values that control the disabled flag.


                  A, perhaps radical, solution: You could extend the renderer of the button tag (com.sun.faces.renderkit.html_basic.ButtonRenderer for the JSF RI 1.2 implementation) and override decode() to allow queuing the ActionEvent on appropriate conditions for your case. If you use Facelets, no extra tag handler is needed. A simple entry in a XML file is all you need to define the new component-renderer combination. This, perhaps together with some JS code in the page, can solve your problem.


                  Otherwise, you need the <a:support> and the annoying server roundtrips.