Month: May 2013

LPIC 1 – Second part completed

Hurray! Today, I completed the second and last part of the LPIC-1. Therefore, I now have the Junior Level Linux certification. Getting prepared for this was tough but I learned a lot from it. Nevertheless, it is time for a switch (I need to recover before going to the second LPIC!). So, I am now going to start preparing for the MySQL 5 Developer certification 🙂

JSF update after validation failed doesn’t work

Are you having problems with the update of a form’s components after a form submission that failed due to validation failure?

If that is so, there is a solution for you in the Omnifaces project. Take a look at the showcase.

By the way, I got to that link from stackoverflow, where the cause of the problem may be understood by considering the following facts, as explained in the previous link by BalusC (the following explanation is from the previous link in stackoverflow and I just copied it here for easier lookup):

  • When JSF validation succeeds for a particular input component during the validations phase, then the submitted value is set to null and the validated value is set as local value of the input component.
  • When JSF validation fails for a particular input component during the validations phase, then the submitted value is kept in the input component.
  • When at least one input component is invalid after the validations phase, then JSF will not update the model values for any of the input components. JSF will directly proceed to render response phase.
  • When JSF renders input components, then it will first test if the submitted value is not null and then display it, else if the local value is not null and then display it, else it will display the model value.
  • As long as you’re interacting with the same JSF view, you’re dealing with the same component state.

So, when the validation has failed for a particular form submit and you happen to need to update the values of input fields by a different ajax action or even a different ajax form (e.g. populating a field depending on a dropdown selection or the result of some modal dialog form, etc), then you basically need to reset the target input components in order to get JSF to display the model value which was edited during invoke action. Otherwise JSF will still display its local value as it was during the validation failure and keep them in an invalidated state.

One of the ways in your particular case is to manually collect all IDs of input components which are to be updated/re-rendered by PartialViewContext#getRenderIds() and then manually reset its state and submitted values by EditableValueHolder#resetValue().

FacesContext facesContext = FacesContext.getCurrentInstance();
PartialViewContext partialViewContext = facesContext.getPartialViewContext();
Collection<String> renderIds = partialViewContext.getRenderIds();

for (String renderId : renderIds) {
    UIComponent component = viewRoot.findComponent(renderId);
    EditableValueHolder input = (EditableValueHolder) component;
    input.resetValue();
}

You could do the previous code inside your invoked method or inside a reuseable ActionListener implementation which you attach as <f:actionListener> to the input component which is calling the listener method.


Coming back to the concrete problem, I’d imagine that this is an oversight in the JSF2 specification. It would make much more sense to us, JSF developers, when the JSF specification mandates the following:

  • When JSF needs to update/re-render an input component by an ajax request, and that input component is not included in the process/execute of the ajax request, then JSF should reset the input component’s value.

This has been reported as JSF issue 1060 and a complete and reuseable solution has been implemented in the OmniFaces library as ResetInputAjaxActionListener (source code here and showcase demo here).