3
votes

After OmniFaces <o:validateMultiple> validation, <p:inputText> values are lost.

I can reporduce problem then web.xml contains parameter javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL:

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

If I remove this parameter - everything works fine.

I have JSF view:

<?xml version="1.0" encoding="UTF-8" ?>
<!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://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:o="http://omnifaces.org/ui">

    <h:form id="someForm">
        <div>
            <o:outputLabel for="bar1" value="Bar1" />
            <p:inputText id="bar1" />
            <p:message for="bar1"/>
        </div>
        <div>
            <o:outputLabel for="bar2" value="Bar2" />
            <p:inputText id="bar2" />
            <p:message for="bar2"/>
        </div>
        <div>
            <o:outputLabel for="bar3" value="Bar3" />
            <h:inputText id="bar3" />
            <h:message for="bar3"/>
        </div>
        <div>
            <o:outputLabel for="bar4" value="Bar4" />
            <h:inputText id="bar4" />
            <h:message for="bar4"/>
        </div>
        <o:validateMultiple components="bar1 bar2 bar3 bar4"
                            validator="#{sameValueValidator}"
                            message="All values shold be the same"
                            showMessageFor="bar2 bar4"/>

        <p:commandButton value="submit" process="@form" update="@form" />
    </h:form>
</html>

and validator:

public class SameValueValidator implements MultiFieldValidator {

    @Override
    public boolean validateValues(FacesContext context,
                                  List<UIInput> components, List<Object> values) {
        if (!values.isEmpty()) {
            Object firstValue = values.get(0);
            for (Object value : values) {
                if (!Objects.equal(firstValue, value)) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }
}

If <o:validateMultiple> validation fails (texts in <p:inputText> components are not the same) <p:inputText id="bar1"> and <p:inputText id="bar2"> become empty, but <h:inputText id="bar3"> and <h:inputText id="bar4"> keep values.

I think <p:inputText> should not lose values or am I doing something wrong?


I am using,

  • PrimeFaces 5.1.14 (or 5.2.RC2)
  • OmniFaces 1.8.1
  • Mojarra 2.2.10
  • Tomcat 8
  • Java 8
1
Can't reproduce it on PF 5.1 + OF 1.8.1 + Mojarra 2.2.10. I don't have PrimeFaces Elite version at hands, but I couldn't reproduce it either on PF 5.2 RC2. Can you reproduce it using PF 5.1 or 5.2 RC2? If so, which JSF impl/version are you using? By the way, OmniFaces has a <o:validateEqual> for the very purpose of validating multiple components on equality.BalusC
Yes I can reproduce this problem using PF RC2, Mojarra 2.2.10. If I remove: javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL param from web.xml - then everything works fine. <o:validateEqual> - has the same problemPalladium

1 Answers

4
votes

It appears that PrimeFaces renderers have a kind of shortcut path when the submitted value is null and the input is invalid while "interpret empty string as null" is enabled, perhaps to circumvent some obscure bug. You can see it in ComponentUtils#getValueToRender() below in the first if statement (line numbers match PF 5.1):

68  if(config.isInterpretEmptyStringAsNull() && submittedValue == null && context.isValidationFailed() && !input.isValid()) {
69      return null;
70  }
71  else if(submittedValue != null) {
72      return submittedValue.toString();
73  }

That part is not taking into account if the component has already a local value set. It could be checked by UIInput#isLocalValueSet().

If you rewrite it as below, then it should work as expected:

68  if(config.isInterpretEmptyStringAsNull() && submittedValue == null && !input.isLocalValueSet() && context.isValidationFailed() && !input.isValid()) {
69      return null;
70  }
71  else if(submittedValue != null) {
72      return submittedValue.toString();
73  }

I could report it to PF guys, but as you appear to have Pro/Elite access, you'd perhaps better do it.