I have a question according to <h:message for="" />
JSF object. I have a JSF 1.1 (yes, unfortunatelly) myFaces project. I've prepared a simple JSP file with label, inputText and message holder:
<h:form id="sacLinkForm">
<cblFaces:outputLabel for="dedicatedCashAccountNumber"
value="#{appBundle.KUSTA_DEDICATED_CASH_ACCOUNT_NUMBER}"/>
<t:inputText id="dedicatedCashAccountNumber"
value="#{createController.modelFE.sacLink.dedicatedCashAccountNumber}"/>
<h:message id="dedicatedCashAccountNumberError"
for="dedicatedCashAccountNumber" />
</h:form>
Also I've created simple validation method:
public static boolean validate(SACLink link) {
boolean isError = false;
FacesContext context = FacesContext.getCurrentInstance();
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
if (StringUtils.isEmpty(link.dedicatedCashAccountNumber)) {
//MessageUtils.addErrorMessage("dedicatedCashAccountNumber", "Dedicated Cash Account Number is mandatory");
message.setSummary("Field mandatory");
message.setDetail("Dedicated Cash Account Number is mandatory");
context.addMessage("sacLinkForm:dedicatedCashAccountNumber", message);
isError = true;
}
return !isError;
}
My problem is with sacLinkForm:dedicatedCashAccountNumber
because compiled JSP has generated id (f.e. _idJsp12:DynTab2:DynView2:tabK.....er:vKustaMa....Controller:sacLinkForm:dedicatedCashAccountNumber
) and it probably causes that addMessage
method doesn't correspond with h:message for=".."
attribute.
So the message is not displayed correctly because java could not find correct h:message
object. Is there any way how to set message to the correct h:message
from Java? I assume that there is no way how to force 'constant' component ID in the JSF 1.1 pages.
Thank you.
You should not be manually performing validation in a JSF action method at all. You should utilize JSF builtin validation facilities. You should use a normal JSF Validator
. Any ValidatorException
which you throw from that will end up in the right message component.
Replace that validate()
method by the following class:
public class AccountNumberValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (StringUtils.isEmpty(value)) {
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary("Field mandatory");
message.setDetail("Dedicated Cash Account Number is mandatory");
throw new ValidatorException(message);
}
}
}
Register it in faces-config.xml
as follows:
<validator>
<validator-id>accountNumberValidator</validator-id>
<validator-class>com.example.AccountNumberValidator</validator-class>
</validator>
Use it in the view as follows:
<t:inputText id="dedicatedCashAccountNumber"
value="#{createController.modelFE.sacLink.dedicatedCashAccountNumber}"
validator="accountNumberValidator" />
That's it. Note that the JSF action method won't be invoked if validation (or conversion) has failed. No need for nonsensicial isError
clutter as well.