11 Replies Latest reply on Feb 16, 2014 8:51 AM by wish79

    Popup panel validation problem

    sensationalist

      Hi.

      I have strange problem with form refreshing and validation. I used richfaces-showcase example (Data Iteration - rich:dataTable - Data Table Edit), but I wanted to use one popup panel for both editing and creating records. But I faced something like bug, so I made the example to show it.

      I made popup panel and two links:

       

      <h:form>
                  Press "New" link or "Edit" link. They don't work. Enter some text to fields and they will begin to work.
                  <a4j:commandLink oncomplete="#{rich:component('beanPanel')}.show()" action="#{testBean.cleanBean}" render="beanPanel" >
                      New
                  </a4j:commandLink>
                  <a4j:commandLink oncomplete="#{rich:component('beanPanel')}.show()" action="#{testBean.editBean}" render="beanPanel" >
                      Edit
                  </a4j:commandLink>
      
                  <rich:popupPanel header="Test bean form" id="beanPanel" autosized="true" domElementAttachment="parent">
                      <rich:messages ajaxRendered="true" globalOnly="true" />
                      <h:panelGrid columns="3" id="userGrid">
                          <h:outputText value="Field1:" />
                          <h:inputText id="field1" label="Field1" value="#{testBean.bean.field1}" required="true">
                              <f:validateLength minimum="3" />
                          </h:inputText>
                          <rich:message for="field1" ajaxRendered="true" />
                          <h:outputText value="Field2:" />
                          <h:inputText id="field2" label="Field2" value="#{testBean.bean.field2}" required="true">
                              <f:validateLength minimum="3" />
                          </h:inputText>
                          <rich:message for="b" ajaxRendered="true" />
                          <h:outputText value="Field3:" />
                          <h:inputText id="field3" label="Field3" value="#{testBean.bean.field3}" />
                          <rich:message for="field3" ajaxRendered="true" />
                      </h:panelGrid>
                      <a4j:commandButton value="Cancel"
                                         onclick="#{rich:component('beanPanel')}.hide(); return false;" />
                  </rich:popupPanel>
              </h:form>
      

       

      Also I made test bean:

       

       

      @ManagedBean(name = "testBean")
      @ViewScoped
      public class TestBean {
      
          public void editBean() {
              bean = beanToEdit;
          }
      
          public void cleanBean() {
              bean = new Bean();
          }
          Bean bean = new Bean();
          Bean beanToEdit = new Bean("val_a", "val_b", "val_c");
      
          public Bean getBean() {
              return bean;
          }
      
          public void setBean(Bean bean) {
              this.bean = bean;
          }
      }
      
      
      public class Bean {
      
          public Bean() {
          }
      
          public Bean(String a, String b, String c) {
              this.field1 = a;
              this.field2 = b;
              this.field3 = c;
          }
          String field1;
          String field2;
          String field3;
      
          public String getField1() {
              return field1;
          }
      
          public void setField1(String a) {
              this.field1 = a;
          }
      
          public String getField2() {
              return field2;
          }
      
          public void setField2(String b) {
              this.field2 = b;
          }
      
          public String getField3() {
              return field3;
          }
      
          public void setField3(String c) {
              this.field3 = c;
          }
      }
      

       

      And what we have here? Edit button don't works at all. All buttons show panel with validation message on first field. BUT if we write something to the fields and press "Cancel" then the buttons will work! Edit will show the values, and New link will erase it. But only first time.What is more strange, that in my application the same example works in another way: "Edit" button works good (may be by <f:setPropertyActionListener target="#{testBean.bean}" value="#{anotherBean}" />) but if I press "New" button first, then panel shows validation messages and both buttons become useless

      So all I want:

      1. To see empty fields and no validation messages on "New" link click.

      2. See filled fields on "Edit" link click.

      What must I do to get it?

       

        • 1. Re: Popup panel validation problem
          usagi

          Try the links with execute="@this". This way the links' AJAX request will not submit all fields (inclusive the ones on the panel).

           

          Also a good practice to add an <a4j:region> around the contents of the panel.

          1 of 1 people found this helpful
          • 2. Re: Popup panel validation problem
            sensationalist

            Thnx a lot. I've added execute="@this" and get the bug I had in my application. If we'll just press this buttons (Edit and New) and then press Cancel - all works fine. But the bug is:

            1. Press "New" and then "Save". We'll see validation messages.

            2. Press "Cancel" to close the popup.

            3. Now press "Edit". What do we see? Not all fields are filled with values Last field is empty. Canceling and pressing "Edit" again don't helps....

            • 3. Re: Popup panel validation problem
              usagi

              Oops, i misunderstood your reply, sorry...

               

              Now, there is no Save button on the panel, so i cannot test whether it is working or not.

              • 4. Re: Popup panel validation problem
                snaker

                I had the same problem and i fixed including <a4j:outputPanel ajaxRendered="true"> inside the form.

                 

                <h:form>

                     <a4j:outputPanel ajaxRendered="true">

                          <a4j:commandLink .....

                     </a4j:outputPanel>

                </h:form>

                 

                Normally, i put the same inside the popupPanel

                 

                <rich:popupPanel>

                     <f:facet name="header">...</>

                     <a4j:outputPanel ajaxRendered="true">

                          <a4j:commandLink ..... (and if i want modify the form when the popup is close i put in the link execute="@form", but if only want modify the popup execute="@this")

                     </a4j:outputPanel>

                </rich:popupPanel>

                • 5. Re: Popup panel validation problem
                  sensationalist

                  Sorry, you are rignt. I missed button. Something like that near "Cancel" button.

                  <a4j:commandButton value="Save" action="#{testBean.save}"

                                                     oncomplete="if (#{facesContext.maximumSeverity==null}) {#{rich:component('beanPanel')}.hide();}" />

                  • 6. Re: Popup panel validation problem
                    sensationalist

                    Sorry, but <a4j:outputPanel ajaxRendered="true"> didn't help (changes nothing). Can't solve this issue After pressing "Save" -> "Cancel" -> "Edit" somefields are not filled. For my test example field3 is not filled with value

                    • 7. Re: Popup panel validation problem
                      okanxyz

                      Me too have the same issue when editing or creating new row in datatable using popupPanel. All works fine until i make a validation mistake on popupPanel, a then my fields in popup panel are not filled with values after i want to edit or create new row.

                      Even more interesting fact is, fields after a field with validation exception are filled with wrong values, other are fine.

                      • 8. Re: Popup panel validation problem
                        okanxyz

                        After whole day testing and testing i manage to figure it out what seems to be a problem. On the components in which validation process pass successfully, didn't triger a update process when i request a popup panel and didn't inject a bean values inside a component. So i did this manualy inside my bean method which trigers a popup showup.

                         

                        Here is my page:

                        pic1.jpg

                         

                        I have to mantion that i put my  table footer content inside a a4j:region :

                        <f:facet name="footer" >

                             <a4j:region>

                                 Link for creating new department

                             </a4j:region>

                        </f:facet>

                         

                        Action method inside a bean for link that create new department

                        public String createNewDepartment()

                        {

                             this.showPopup = true;

                             this.sifra = " "; // i make a space so that my validation pass correctly;

                             this.naziv1 = " ";

                             this.naziv2 = " ";

                         

                             //manual call of calidation and update process of components on popup panel

                                FacesContext context = FacesContext.getCurrentInstance();

                                UIComponent com3 = context.getViewRoot().findComponent("odsjeciForm:sifra");

                                UIComponent com1 = context.getViewRoot().findComponent("odsjeciForm:naziv1");

                                UIComponent com2 = context.getViewRoot().findComponent("odsjeciForm:naziv2");        

                                com1.processValidators(context);

                                com1.processUpdates(context);

                                com2.processValidators(context);

                                com2.processUpdates(context);

                                com3.processValidators(context);

                                com3.processUpdates(context);

                         

                             this.sifra = ""; //empty string like it's supposed to be

                             this.naziv1 = "";

                             this.naziv2 = "";

                             return null;    

                        }

                         

                        It give me this:

                         

                             pic2.JPG

                         

                        All my fields are empty like it's supposed to be.

                         

                        Action method inside a bean for link that edits a existing department

                        public String createNewDepartment()

                        {

                             this.showPopup = true;    

                         

                             //manual call of calidation and update process of components on popup panel

                                FacesContext context = FacesContext.getCurrentInstance();

                                UIComponent com1 = context.getViewRoot().findComponent("odsjeciForm:naziv1");

                                UIComponent com2 = context.getViewRoot().findComponent("odsjeciForm:naziv2");        

                                com1.processValidators(context);

                                com1.processUpdates(context);

                                com2.processValidators(context);

                                com2.processUpdates(context);

                         

                         

                        importValues(); //method that fill the bean properties with values of deparment which have to be edited.

                             return null;    

                        }

                         

                        And method give me this:

                         

                        pic3.JPG

                         

                        My popup Panel and my datatable are in the same form. Next, for showing popup panel i call one of the previous methods which set a flag showPopup to true. My attribute show of popup panel tag is ... show="#{odsjeciForm.showPopup}".

                         

                        I really appriciate if someone post a simpler solution.

                        • 9. Re: Popup panel validation problem
                          jeffpoos

                          I just posed this

                           

                          https://community.jboss.org/thread/199381?tstart=0

                           

                          which shows the same error you describe in the richfaces demo. 

                           

                          Did anyone come up with a better solution?

                          • 10. Re: Popup panel validation problem
                            khosro_question

                            I think the only solution is the one that Eldin Okanovic suggested.

                            Also the same workaround  described here(https://issues.jboss.org/browse/RF-11413).

                            I think the general solution maybe finding all InputText component in Popup and doing processValidators and processUpdates manually on them.

                            We can pass id of Popup panel as a request parameter.


                             

                            
                                      public void processPopUpPanel() {
                                                /*
                                                 * We use it because of bug in Richfaces :
                                                 * 2.https://community.jboss.org/message/734283
                                                 * 3.https://community.jboss.org/thread/199381?tstart=0
                                                 * 4.https://issues.jboss.org/browse/RF-12238
                                                 * 5.https://community.jboss.org/message/734584#734584
                                                 * 6.https://issues.jboss.org/browse/RF-11413
                                                 */
                                                FacesContext context = FacesContext.getCurrentInstance();
                                          String idOfPopUpPanel=       ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getParameter("idOfPopUpPanel");
                                                UIComponent com3 = context.getViewRoot().findComponent(idOfPopUpPanel);
                                                recursivleyFindHtmlInputText(com3, context);
                                      }
                            
                            
                                      public void recursivleyFindHtmlInputText(UIComponent component, FacesContext context) {
                                                List<UIComponent> components = component.getChildren();
                                                if (components != null) {
                                                          for (UIComponent uiComponent : components) {
                                                                    if (uiComponent instanceof HtmlInputText) {
                                                                              HtmlInputText htmlInputText = (HtmlInputText) uiComponent;
                                                                              htmlInputText.processValidators(context);
                                                                              htmlInputText.processUpdates(context);
                                                                    } else {
                                                                              if (uiComponent instanceof javax.faces.component.UINamingContainer) {
                                                                                        /*
                                                                                         * This is because of getting child of composite
                                                                                         * component. Like in orgsAddPopup.xhtml
                                                                                         * <layout:simpleDecorate labelWidth="150px" id="d" >
                                                                                         */
                                                                                        UIComponent childrenHolderFacet = uiComponent.getFacets().get(
                                                                                                            "javax.faces.component.COMPOSITE_FACET_NAME");
                                                                                        if (childrenHolderFacet != null) {
                            
                            
                                                                                                  for (Iterator<UIComponent> childrenIt = childrenHolderFacet.getChildren()
                                                                                                                      .iterator(); childrenIt.hasNext();) {
                                                                                                            recursivleyFindHtmlInputText(childrenIt.next(), context);
                                                                                                  }
                                                                                        }
                                                                              } else {
                                                                                        recursivleyFindHtmlInputText(uiComponent, context);
                                                                              }
                                                                    }
                                                          }
                                                }
                                      }
                            
                            

                             

                             

                            Khosro.

                            • 11. Re: Popup panel validation problem
                              wish79

                              Try to render something on the caller page from the submit button on the popup , this case solved my problem.