13 Replies Latest reply on Nov 9, 2010 9:44 AM by Some Kid

    "Required" attribute results in action not being executed

    Some Kid Newbie

      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 Master

          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
            Some Kid Newbie
            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.

            • 4. Re: "Required" attribute results in action not being executed
              Ilya Shaikovsky Master
              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
                Some Kid Newbie

                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)]



                • 7. Re: "Required" attribute results in action not being executed
                  Ilya Shaikovsky Master

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

                  • 9. Re: "Required" attribute results in action not being executed
                    ram sundaram Newbie

                    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
                      Some Kid Newbie

                      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
                        ram sundaram Newbie

                        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
                          Some Kid Newbie

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

                          • 13. Re: "Required" attribute results in action not being executed
                            Some Kid Newbie

                            Hi everybody,

                            I tried all suggestions but so far without luck.

                            Any ideas?