Note that there are some explanatory texts on larger screens.

plurals
  1. POParent UIInput is not converted/validated when immediate="true" is set on <f:ajax>
    text
    copied!<p>I observed following behaviour in JSF:</p> <p>A UIInput component triggered via AjaxBehaviour with 'immediate=true' does not have the validator executed in the APPLY_REQUEST, but always in the Phase determined by the UIInput itself. It means the AjaxBehaviour 'immediate' attribute has no effect on when the validator of the component is processed. Which is IMO not what the describtion of AjaxBehaviour says: </p> <blockquote> <p>The immediate attribute indicates whether user inputs are to be processed early in the application lifecycle or later. If the attribute is set to true, events generated from this component are broadcast during the Apply Request Values phase. Otherwise, the events will be broadcast during the Invoke Applications phase.</p> </blockquote> <p>To be read at: <a href="http://docs.oracle.com/javaee/6/tutorial/doc/gkace.html#gkhwm" rel="nofollow">Oracle Tutorial</a></p> <p>Even thought in AjaxBehaviour.isImmediate(component,behaviour) JSF takes care of having the AjaxBehaviour more important than the component </p> <pre><code>private boolean isImmediate(UIComponent component, AjaxBehavior ajaxBehavior) { boolean immediate = false; if(ajaxBehavior.isImmediateSet()) { immediate = ajaxBehavior.isImmediate(); } else if(component instanceof EditableValueHolder) { immediate = ((EditableValueHolder)component).isImmediate(); } else if(component instanceof ActionSource) { immediate = ((ActionSource)component).isImmediate(); } return immediate; } </code></pre> <p>Whereas in the UIInput.processDecodes(context) does not trigger the validation in that phase because the component is not 'immediate' .. </p> <pre><code>public void processDecodes(FacesContext context) { if (context == null) { throw new NullPointerException(); } // Skip processing if our rendered flag is false if (!isRendered()) { return; } super.processDecodes(context); if (isImmediate()) { executeValidate(context); } } </code></pre> <p>Anyways; to reproduce my case:<br> A) The JSF code:</p> <pre><code>&lt;h:selectBooleanCheckbox id="mandatory" value="#{currentQuestion.mandatory}" label="#{texts.mandatory_Question}" disabled="#{!bean.metadata.editable}" validator="mandatoryValidator" onchange="makeDirty()" immediate="false"&gt; &lt;f:ajax event="click" execute="@this" render="@this :mandatory-msg" immediate="true"/&gt; &lt;/h:selectBooleanCheckbox&gt; &lt;h:outputLabel for="mandatory" value="#{texts.mandatory_Question}" styleClass="standard-label chkBox-label" /&gt; &lt;p:message for=":mandatory" id="mandatory-msg" showDetail="true" showSummary="true" /&gt; </code></pre> <p>B)The custom validator: </p> <pre><code>@FacesValidator("mandatoryValidator") public class MandatoryValidator implements Validator { /** logger. */ private static final Logger LOG = Logger.getLogger(MandatoryValidator.class.getName()); /** {@inheritDoc} */ @Override public final void validate(final FacesContext context, final UIComponent component, final Object value) { if (FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.APPLY_REQUEST_VALUES) { LOG.debug("apply phase"); } if (FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.PROCESS_VALIDATIONS) { LOG.debug("validation phase"); } } </code></pre> <p>In that example the validator will not be executed in the APPLY_REQUEST until the SelectBoolCheckBox is also 'immediate=true'. Even worse, the immediate of the component, even defaulted, always wins. Which makes the AjaxBehaviour immediate attribute totally worthless. </p> <p>Can anyone explain or reproduce or grunt with me?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload