13 Replies Latest reply on Nov 9, 2010 9:44 AM by sam-user

    "Required" attribute results in action not being executed

    sam-user

      Hello,

      I have an application based on Seam 2.1.1 and Richfaces 3.3.1 and I came across to a rather strange thing.

      I have a field where the users enter a value. This value is used to pupulate another field from the form. The second field is a "required" field.

      The problem is that if the user types a value in the first field and then submits the form by clicking directly to the submit button, then the action on the "oncomplete" event is not executed.

       

      The code below is a simplified version of the actual code, but it behaves exactly the same way - if I enter a value in field1 and click directly on "Submit" -

       

      .

       

      <!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"
               xmlns:s="http://jboss.com/products/seam/taglib">

      <ui:composition template="layout/template.xhtml">
               <ui:define name="body">
                       <h:form>
                               <h:panelGrid columns="2">
                                       <s:decorate id="codeField" template="layout/edit.xhtml">
                                               <ui:define name="label">Code </ui:define>
                                               <h:inputText value="#{test.s}" valueChangeListener="#{test.action1}"  id="field1">
                                                       <a4j:support event="onblur" reRender="codeField" ajaxSingle="true"/>

                                              </h:inputText>
                                               <h:inputText value="#{test.valueOfBean}" id="outtext" required="true"/>
                                       </s:decorate>                 

                              </h:panelGrid>
                               <h:panelGrid columns="2">
                                       <a4j:commandButton action="#{test.action2}" value="Submit"
                                               eventsQueue="q1" oncomplete="#{test.action3()}" />
                               </h:panelGrid>
                       </h:form> 
               </ui:define>
      </ui:composition>

      </html>

       

       

      package come.package;

      import javax.faces.event.ValueChangeEvent;

      import org.jboss.seam.Component;
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Scope;

      @Name("test")
      @Scope(ScopeType.CONVERSATION)
      public class Test
      {
              
              private String s;
              
              public void action1(ValueChangeEvent event)
               {

                      System.out.println("Executing action 1");
                       String c= (String) event.getNewValue();
                       setValueOfBean(c);
               }
              
              public void action2()
               {
                       System.out.println("Executing action 2");
               }

             public String getS() {
                      return s;
               }

             public void setS(String s) {
                       System.out.println("Setting the valueOfBean to " + s);
                      this.s = s;
               }

             private String valueOfBean;
              
              public String getValueOfBean() {
                      return valueOfBean;
               }

             public void setValueOfBean(String valueOfBean) {
                       System.out.println("Setting the valueOfBean to " + valueOfBean);
                      this.valueOfBean = valueOfBean;
               }
              
              
              public void action3()
               {
                       System.out.println("Executing action 3");
               }
      }

       

      The action "test.action2" of the command button  is not executed and I get a warning saying

       

      INFO  [lifecycle] WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
      sourceId=j_id30:codeField:outtext[severity=(ERROR 2), summary=(value is required), detail=(value is required)]

      I tried using queues, but that didn't change anything.

       

      If I remove the required attribute from field "outtext" however, test.action2 is executed.

       

      Could someone tell me if this is a bug or if there's something wrong with the code.

      Thanks.

        • 1. Re: "Required" attribute results in action not being executed
          ilya_shaikovsky

          1) you can't define server side action in oncomplete - as it's client side handler (like onclick). So it will not works in any way.

          2) in general implemented case looks just as it should hitting the button - the field remains empty and Faces message risen refects current state fine. You could - set onkeypress as support event in order suggestions to be populated before hitting the button in any way. But that requires some additional tunning:

               2.1) change reRender to just second input (or the focus will be lost during typing)

               2.2) set some reasonable defaults for requestDelay and set ignoreDupResponse to true in order not to flood the server much with requests on every keypress.

          • 2. Re: "Required" attribute results in action not being executed
            sam-user
            1) you can't define server side action in oncomplete - as it's client  side handler (like onclick). So it will not works in any way.

            The actual code is different, this was for demonstration purposes only, but action3() is being  called none the less. The problem is not with the oncomplete however. The problem is that the action of the command button (action2) is not being executed if the required attributed if the "outtext" field is set to true. If it is set to false - then the action is executed.

             

            2) in general implemented case looks just as it should hitting the button - the field remains empty and Faces message risen  refects current state fine. You could - set onkeypress as support event  in order suggestions to be populated before hitting the button in any  way. But that requires some additional tunning

            I'm not sure I understand this. Could you explain a bit more what you mean.

             

            2.1) change reRender to just second input (or the focus will be lost during typing)

            This,funily enough results in field "outtext" not being populated at all

             

            2.2) set some reasonable defaults for requestDelay and set  ignoreDupResponse to true in order not to flood the server much with  requests on every keypress.

            Tried with values up to 5 sec - no change.

             

            I forgot to add in my initial post that I compared the client side logs in both cases (with required set to true and false, respectively) but they were the same.

            • 3. Re: "Required" attribute results in action not being executed
              sam-user

              Anyone?

              • 4. Re: "Required" attribute results in action not being executed
                ilya_shaikovsky
                I'm not sure I understand this. Could you explain a bit more what you mean.

                INFO  [lifecycle] WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
                sourceId=j_id30:codeField:outtext[severity=(ERROR 2), summary=(value is required), detail=(value is required)]

                 

                prevents all the lifecycle activities except render response and caused by the fact that:

                 

                <h:inputText value="#{test.s}" valueChangeListener="#{test.action1}"  id="field1">
                <a4j:support event="onblur" reRender="codeField" ajaxSingle="true"/>

                 

                </h:inputText>
                <h:inputText value="#{test.valueOfBean}" id="outtext" required="true"/>

                when you field changed and focus lost - second input updated with some value according to input in the first one.

                 

                But when you clicking directly to the button - there are two problems:

                1. two concurrent requests sent - one from suport and second from button
                2. second request from button sent when the field is empty (request which should update field still in progress)  - so required validation fails.

                 

                So still the same suggestions

                • use onkeyup for support
                • add queue to the page
                • add some requestDelay to support (500 ms I think enough)

                 

                2.1) change reRender to just second input (or the focus will be lost during typing)

                 

                This,funily enough results in field "outtext" not being populated at all

                should works. need more details. (maybe some other messages in server log or a4j:log)

                • 5. Re: "Required" attribute results in action not being executed
                  sam-user

                  Thanks Ilya.

                  I followed your advice and changed the support event to "onkeyup" and also added a queue.

                   

                  <!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"
                      xmlns:s="http://jboss.com/products/seam/taglib">
                  <ui:composition template="layout/template.xhtml">
                       <ui:define name="body">
                           <h:form>
                               <a4j:queue name="q1" />
                                  <h:panelGrid columns="2">
                                      <s:decorate id="codeField" template="layout/edit.xhtml">
                                          <ui:define name="label">Code  Required</ui:define>
                                          <h:inputText value="#{test.s}" valueChangeListener="#{test.action1}" >
                                              <a4j:support event="onkeyup" reRender="codeField" ajaxSingle="true" eventsQueue="q1" ignoreDupResponses="true"/>
                                          </h:inputText>
                                          <h:inputText value="#{test.valueOfBean}" id="outtext" required="true" />
                                      </s:decorate>  
                                  </h:panelGrid>
                                  <h:panelGrid columns="2">
                                        <a4j:commandButton action="#{test.action2}" value="Submit" requestDelay="5000" ignoreDupResponses="true"
                                           eventsQueue="q1" oncomplete="#{test.action3()}" />
                                  </h:panelGrid>
                           </h:form>             
                       </ui:define>
                  </ui:composition>
                  </html>

                  The result however is still the same. Here's the log extract:

                   

                  11:27:15,742 INFO  [STDOUT] Executing action 1
                  11:27:15,742 INFO  [STDOUT] Setting the valueOfBean to 12
                  11:27:15,742 INFO  [STDOUT] Setting the valueOfBean to 12
                  11:27:16,023 INFO  [STDOUT] Executing action 1
                  11:27:16,023 INFO  [STDOUT] Setting the valueOfBean to 123
                  11:27:16,023 INFO  [STDOUT] Setting the valueOfBean to 123
                  11:27:21,085 INFO  [STDOUT] Executing action 1
                  11:27:21,085 INFO  [STDOUT] Setting the valueOfBean to 123
                  11:27:21,085 INFO  [STDOUT] Executing action 3
                  11:27:21,117 INFO  [lifecycle] WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
                  sourceId=j_id30:codeField:outtext[severity=(ERROR 2), summary=(value is required), detail=(value is required)]



                  • 6. Re: "Required" attribute results in action not being executed
                    sam-user

                    Any thoughts, anyone?

                     

                    • 7. Re: "Required" attribute results in action not being executed
                      ilya_shaikovsky

                      show please a4j:log output for those requests (attach text file to thread.)

                      • 8. Re: "Required" attribute results in action not being executed
                        sam-user

                        Thanks Ilya,

                        file attached.

                        • 9. Re: "Required" attribute results in action not being executed
                          rammyramkumar

                          If i understand your question , i dont think you can specify EL in oncomplete attribute.

                           

                          use jsfunction tag.

                           

                           <a4j:commandButton action="#{test.action2}" value="Submit" requestDelay="5000" ignoreDupResponses="true" 
                                                   eventsQueue="q1" oncomplete="jsFunctionName();" />

                           

                          <a4j:jsFunction name="resetMemberSearchPage"
                          action="#{navigationBean.resetMemberSearchPage}"
                          reRender="memberSearchBodyPanel,resultTable,selectAllCheckBox" />

                          <a4j:jsFunction name="jsFunctionName"

                          action="#{bean.actionMethod}"

                          reRender="componentId" />

                           

                          Hope this helps.

                          • 10. Re: "Required" attribute results in action not being executed
                            sam-user

                            I'm afraid it doesn't.

                            If you read the original post the problem is that the action is not being executed, not the oncomplete. And it only happens when the second control is set to required.

                            Thanks for the effort anyway.

                            • 11. Re: "Required" attribute results in action not being executed
                              rammyramkumar

                              i think i misunderstood ur question.

                               

                                <h:inputText value="#{test.valueOfBean}" id="outtext" required="true" />
                              need more insight.... is your backing bean - request scoped?
                              • 12. Re: "Required" attribute results in action not being executed
                                sam-user

                                It's all in the post. Logs also attached.

                                • 13. Re: "Required" attribute results in action not being executed
                                  sam-user

                                  Hi everybody,

                                  I tried all suggestions but so far without luck.

                                  Any ideas?