5 Replies Latest reply on Oct 24, 2007 6:46 PM by jeffzzang

    Component does not reRender after input validation fails

    bpeng

      Hi,

      I've seen this problem posted, but never a solution for it. If there is a solution, please kindly reply and direct me to it. The problem is as follows:

      InputText component is tied to inputTextarea component with ajax4jsf as follows:

      <h:form>
      <a4j:outputPanel>
      <t:messages/>
      </a4j:outputPanel>
      </h:form>

      <h:form>

      <a4j:region renderRegionOnly="false">
      <t:inputText id="testCaseDescriptionInput" size="20" value="#{BackingBean.description}">
      <a4j:support reRender="inputDisplay" ajaxSingle="true" event="onkeyup"/>
      </t:inputText>
      </a4j:region>

      <t:inputTextarea id="inputDisplay" value="#{BackingBean.testCaseString}" validator="#{BackingBean.validateInput}"/>

      <a4j:commandButton value="#{BackingBean.addTestCase}"/>

      </h:form>

      testCaseString has both a setter and a getter defined because inputTextarea is used both as a display panel and an editable textarea.

      As you can tell, as inputs are being entered in the inputText component, the inputTextarea component is being updated simultaneously (on "onkeyup" event). It functions perfectly, until the commandButton is clicked on, the input validator method throws a ValidatorException due to bad input, and the error message is displayed on the JSP. Then the problem occurs - entering input into the inputText component no longer updates the inputTextarea component.

      I tried the following with no luck:
      - surround inputTextarea component with the <a4j:OutputPanel> tag and reRender the OutputPanel instead of the inputTextarea.
      - update to ajax4jsf 1.1.1 from 1.1.0.

      I've also put in some print statements into the description setter method and testCaseString getter method. And I discovered that after input validation fails and the problem occurs, the getter of testCaseString is no longer being called as it should be!

      Does anyone have a solution to this problem?

      This is an urgent request. Please HELP!

      Bailey

        • 1. Re: Component does not reRender after input validation fails

          I have no idea, why you surround the <t:messages/> with h:form, but anyway, surrounding with a4j:outputPanel starts to be useful in you add ajaxRendered="true" there.

          • 2. Re: Component does not reRender after input validation fails
            bpeng

            Hi Sergey,

            Thanks for the response. Actually I did have the ajaxRendered="true" attribute in the a4j:outputPanel tag, I just forgot that part in my post. Thanks for pointing that out. But anyway, that does not at all help solve the problem. The problem seems to be that when the form is submitted and an input validation returns an error back to the page, the reRender of the inputTextarea doesn't get updated - for some reason, the getter method is not being called. And the strange thing is that the setter on the inputText component is called.
            So basically, the flow is this:
            1) user submits form with invalid input
            2) form validator returns with error message
            3) user enters some input into inputText
            4) inputText calls setter method as user enters input
            5) inputText attempts to reRender inputTextarea to reflect changes
            6) inputTextarea doesn't call getter method to show changes

            This seems to be a problem for a lot of people out there and nobody has gotten answers for it.

            • 3. Re: Component does not reRender after input validation fails

              May be you miss something also in your post, but i did not see the sense from what your code shows. a4j:support tries to reRender the text area, however it has no action or action listener that might change the "#{BackingBean.testCaseString}".

              • 4. Re: Component does not reRender after input validation fails
                bpeng

                I see what you mean. We're getting into the backend part that I did not include in my snippet up there. So here it is:

                The getter method for testCaseString in BackingBean calls the toString() method of a TestCase object. The TestCase object contains a description attribute, which

                <t:inputText value="#{BackingBean.description}">
                <a4j:support event="onkeyup" reRender="inputDisplay"/>
                </t:inputText>

                sets as the user presses every keystroke. The scope of BackingBean is session.

                Remind you that this code works perfectly fine before the form is submitted OR if the form submission contains all VALID input. In the event that all inputs are valid and the form gets submitted, the action method, #{BackingBean.addTestCase} just returns to the same page.
                I have a feeling that when the form submission causes the validator to fail and throw an exception, Javascript is unable to locate the inputTextarea component via its ID to cause reRendering. Let me know if you can try this simple example for me as a way to help me get to the bottom of this issue. I've already tried it and the same problem occurs:

                1) Create a JSP with the following

                <t:panelGrid columns="1">

                <t:panelGroup id="errorMessagePanelGroup">
                <t:messages/>
                </t:panelGroup>

                <h:form id="addTestCaseForm">
                <t:panelGrid columns="2">
                <t:outputLabel for="inputText" value="Input"/>
                <a4j:region id="region" renderRegionOnly="false">
                <t:inputText id="inputText" value="#{AddTestCaseBean.input}">
                <a4j:support event="onkeyup" reRender="textArea"/>
                </t:inputText>
                </a4j:region>

                <t:inputTextarea id="textArea" value="#{AddTestCaseBean.input}" validator="#{AddTestCaseBean.validate}"/>

                <a4j:commandButton action="#{AddTestCaseBean.runAction}" value="submit" reRender="errorMessagePanelGroup,inputText,textArea"/>
                </t:panelGrid>
                </h:form>

                </t:panelGrid>


                2) Create a backing bean class as follows:

                public class AddTestCaseBean {
                public String input = null;

                public String getInput() {
                return input;
                }
                public void setInput(String inp) {
                input = inp;
                }

                public String runAction() {
                input = null;
                return "addTestCasePage";
                }

                public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
                String val = (String)value;
                if (val.indexOf("test") != -1) {
                FacesMessage message = new FacesMessage();
                message.setDetail("Test error");
                message.setSummary("Test error");
                message.setSeverity(FacesMessage.SEVERITY_ERROR);
                throw new ValidatorException(message);
                } else {
                input = null;
                }
                }
                }

                3) Enter "test" in the <t:inputText>. As you are typing, you will see the word "test" come up in <t:inputTextarea>.

                4) submit the form by hitting the submit button

                5) At this point, the page should return and say "Test Error" on top of the page.

                6) Try to enter something into <t:inputText> and you will see that the <t:inputTextarea> doesn't get updated anymore.

                7) Try to submit the form with anything but the word "test" in <t:inputTextarea>.

                8) No error should be generated, and the reRendering works again.

                I appreciate your feedback.

                Bailey

                • 5. Re: Component does not reRender after input validation fails
                  jeffzzang

                  I am having the same exact problem. Does anyone know why this happens?