Monday, June 28, 2010

Submitted value, local value, model value ...

There are 4 places where the value is stored during JSF lifecycle.
  1. The typed value comes with a request and is placed into request parameter map.
  2. Then the "submitted value" of component will be set.
  3. The "submitted value" is checked against the converter and only if it's OK the "local value" is updated and the "submitted value" is cleaned up.
  4. Then, only if validation und update phases are passed successfully, the "model value" (e.g. #{foo.bar}) is updated and the "local value" is cleaned up.

Assume, the user enters a wrong date. The page after reload should show the value user entered, but not the old one from the model. Therefore, the algorithmus in the render response phase is the following:
- if a submitted value is not empty, grab it and show.
- otherwise, if a local value is not null, show it.
- otherwise, call a getter of the model value and show it.

Unfortunately, but some JSF component libraries forget this fact. I use PrimeFaces - a great, JSF 2 "ready", rapidly evolving component library and more. I didn't check all components, but at least two components don't consider submitted values in the current release 1.0.2 / 2.0.2. That are: PickList and Calendar. I had to write a customizing code during markup encoding because it's important e.g. for failed validation or wizard like functionality.

PickListRenderer
DualListModel model;
Object submittedValue = pickList.getSubmittedValue();
if (submittedValue != null) {
    model = (DualListModel) getConvertedValue(facesContext, pickList, submittedValue);
} else {
    model = (DualListModel) pickList.getValue();
}
CalendarRenderer
String valueAsString;
if (calendar.getSubmittedValue() != null) {
   valueAsString = (String) calendar.getSubmittedValue();
} else {
   valueAsString = CalendarUtils.getValueAsString(facesContext, calendar);
}

1 comment:

Note: Only a member of this blog may post a comment.