7

In both MyFaces and Mojarra 2.1, there exists a defect where when javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL is set to true, any fields that are marked as required and pre-populated in the model, when blanked-out and submitted are re-shown with their original non-blanked-out values instead of being left blank.

Scenario is:

  1. User loads page with a single required field that is populated with existing data from the model
  2. User clears out the field on the page and submits the form
  3. Validation fails, as expected, and the user is shown an error message that they must fill in the required field.

The issue is that the field, which should show what the user submitted -- which is that they submitted a blank value for the field -- is instead populated with the original value from the model. The only workaround is to set javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL to false. Setting to false delivers the desired behavior that the field remains blanked out when the page is redisplayed with the required field error message.

A defect was logged with Mojarra (http://java.net/jira/browse/JAVASERVERFACES-2375) and MyFaces (https://issues.apache.org/jira/browse/MYFACES-3525) but no progress has been made in 6 weeks.

Note that it appears Mojarra had a similar issue reported over 6 mos ago yet no progress has been made.

Does anyone know of a workaround for this where we can keep javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL set to true instead of false and yet not encounter this required field usability issue?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
BestPractices
  • 12,738
  • 29
  • 96
  • 140

1 Answers1

9

This problem is explained in detail in JSF 2 - Bean Validation: validation failed -> empty values are replaced with last valid values from managed bean. To the point, in Mojarra it's caused by a bug or at least an oversight in HtmlBasicRenderer#getCurrentValue() and has been reported as issue 2266.

In the meanwhile, the easiest way to workaround this, while taking 3rd party component libraries with their own renderers like PrimeFaces into account, is to copy the source file of UIInput straight in your project's source folder and then edit the getSubmittedValue() accordingly:

public Object getSubmittedValue() {
    if (submittedValue == null && !isValid() && considerEmptyStringNull(FacesContext.getCurrentInstance())) {
        return "";
    }
    else {
        return submittedValue;
    }
}

It'll end up in /WEB-INF/classes and this will get precedence in classloading above the one in the JSF JAR file. Admittedly, it's somewhat clumsy, but it's less painful than rebuilding the JSF JAR file or overriding every single input renderer.

Martin Höller
  • 2,714
  • 26
  • 44
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Should this also fix it for ? I see that is fixed with this, but it doesnt appear to fix Do you happen to know the fix for PrimeFaces? – BestPractices May 22 '12 at 17:53
  • 1
    PrimeFaces job is done in `ComponentUtils#getValueToRender()` method. – BalusC May 22 '12 at 17:56
  • Thinking once more about this, it's maybe more easy if `UIInput#getSubmittedValue()` is instead altered to return an empty string instead of `null` when `isValid()` is `false`. – BalusC May 22 '12 at 17:59
  • Thanks-- did you want to update http://java.net/jira/browse/JAVASERVERFACES-2262 to include this fix rather the original fix? Quick question-- are you confident that this new fix won't break anything else? – BestPractices May 22 '12 at 18:20
  • I've already updated the ticket. No it won't break anything else considering that `getSubmittedValue()` is only used internally. Whenever you're using for example custom validators for multiple components, you may only need to change the logic to take this into account (so don't only check for `null`, but also for empty string), but letting such a validator depend on a context param is already not a good idea in first place. – BalusC May 22 '12 at 18:23
  • Do you have any insight into when this fix might make it into Mojarra? Its been 6 mos since it was reported and seems like an important fix... – BestPractices May 22 '12 at 18:26
  • 1
    Sorry, I don't have any insight in the Mojarra dev team planning. All you can to is to vote the issue up. – BalusC May 22 '12 at 18:30
  • I'm not doing any Bean-based validation, so it seems like I should simply keep the context parameter set to its default value of false and check for null or empty string for submitted fields. Note, I have a "StringTrimmer" Converter enabled that will trim any leading or lagging whitespace from submitted Strings. Since I'm already processing all String-bsaed fields and trimming them, what if I just had the StringTrimmer converter return null if, after trimming, the value was an empty string? That way I dont have to "patch" the JSF library and I get the value of only having to check for null... – BestPractices May 22 '12 at 19:39
  • That's also a good possibility. If you configure it as `@FacesConverter(forClass=String.class)`, it'll be automatically applied on all strings. – BalusC May 22 '12 at 19:41
  • 1
    This is fixed in PrimeFaces 3.5 with an improved patch. – Cagatay Civici Dec 26 '12 at 09:50