org.omnifaces.component.input.InputHidden Maven / Gradle / Ivy
/*
* Copyright 2020 OmniFaces
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.omnifaces.component.input;
import javax.faces.component.FacesComponent;
import javax.faces.component.html.HtmlInputHidden;
import javax.faces.context.FacesContext;
/**
*
* The <o:inputHidden>
is a component that extends the standard <h:inputHidden>
* and changes the behavior to immediately convert, validate and update during apply request values phase, regardless of
* any conversion/validation errors on other UIInput
components within the same form. The standard
* <h:inputHidden>
follows the same lifecycle as other UIInput
components which is in
* the end unintuive as hidden input fields are usually under control of the developer.
*
* Use case 1: Imagine a form with a <h:inputHidden>
and a <h:inputText>
. The
* hidden input holds some prepopulated value of a request scoped bean which is intended to be passed through to the
* request scoped bean instance of the next request. However, when conversion/validation fails on the text input, then
* the hidden input won't update the bean property and then becomes empty. I.e. the original value gets permanently lost.
* This can be bypassed by using ajax to update only specific fields, but this will fail when the update of the hidden
* input is actually needed (e.g. because the value can possibly be adjusted in action/listener method).
*
* Use case 2: Imagine a form with an UIInput
or UICommand
component whose
* rendered
attribute relies on a request scoped bean property which is retained for the next request
* through a <h:inputHidden>
. However, when JSF needs to decode the UIInput
or
* UICommand
component during the postback, the rendered
attribute has defaulted back to
* false
because the <h:inputHidden>
hasn't yet updated the request scoped bean property
* yet.
*
* This behavior cannot be achieved by using immediate="true"
on <h:inputHidden>
. It
* would only move the conversion/validation into the apply request values phase. The model still won't be updated on
* time.
*
*
Usage
*
* You can use it the same way as <h:inputHidden>
, you only need to change h:
into
* o:
to get the "immediate v2.0" behavior.
*
* <h:form>
* <o:inputHidden value="#{bean.hidden}" />
* ...
* </h:form>
*
*
* When using ajax, don't forget to make sure that the component is also covered by the execute
attribute.
*
* @author Bauke Scholtz
* @since 3.7
*/
@FacesComponent(InputHidden.COMPONENT_TYPE)
public class InputHidden extends HtmlInputHidden {
// Public constants -----------------------------------------------------------------------------------------------
public static final String COMPONENT_TYPE = "org.omnifaces.component.input.InputHidden";
// Actions --------------------------------------------------------------------------------------------------------
/**
* This override performs decode, validate and update at once.
*/
@Override
public void decode(FacesContext context) {
super.decode(context);
validate(context);
if (isValid()) {
updateModel(context);
}
}
/**
* This override which does effectively nothing prevents JSF from performing validation for second time.
*/
@Override
public void processValidators(FacesContext context) {
// NOOP.
}
/**
* This override which does effectively nothing prevents JSF from performing update for second time.
*/
@Override
public void processUpdates(FacesContext context) {
// NOOP.
}
}