Skip to main content

[webtier] Custom validator, empty inputTextarea

7 replies [Last post]
Anonymous

Hello,

I wonder how I can write a custom validator that conditionally validates
a non-required h:inputTextarea, depending on the state of an
h:selectBooleanCheckbox. The validation should fail if the inputTextarea is
empty and the selectBooleanCheckbox is not checked.
When adding a custom validator to the h:inputTextarea I have the problem
that validate() is not called as long as there is no content in the
inputTextarea. But I would like the validator to be consulted particularly
when the inputTextarea is empty, since this is part of the validation rule.

Any idea how to solve this? I am thinking about adding a custom validator
to the selectBooleanCheckbox and rendering the error message for the
inputTextarea within this validator. But I don't like adding a validator
to one component in order to check the validity of another.

Best regards Uwe

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
rogerk
Offline
Joined: 2004-05-06
Points: 0

What you are describing seems very similar to multiple field validation.
As you know, validators are typically tied to components. However,
you could have a validator method in a backing bean, that references
multiple components.

Uwe Seimet

> What you are describing seems very similar to multiple field validation.
> As you know, validators are typically tied to components. However,
> you could have a validator method in a backing bean, that references
> multiple components.

Are you thinking of validating within an action method? That's too late
because validating (and rendering the error message) in the action
means that the validation error is not rendered together with the error
messages of other (standard) validators. There are several fields to be
validated and for consistency I want all validation errors to be rendered
before the action method is called, just like this is the case with
custom validators.

--
-----------------------------------------------------------------------
Dr. Uwe Seimet http://www.seimet.de/

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

jkva
Offline
Joined: 2005-04-06
Points: 0

I think Roger is talking about validation methods that you put inside a backing bean, like shown here:
http://www.ibm.com/developerworks/library/j-jsf3/#N105E7

If you want to go berserk, you could also create a custom validator that conditionally checks required fields.

That way, you'll get something like this:



Or to make it more reusable:



jkva
Offline
Joined: 2005-04-06
Points: 0

Hrm, I've just looked it up in the sources. It's not possible to create a custom Validator for required fields, since required is handled as a special case in UIInput. This prevents your custom required Validator to be called, since UIInput prevents this.

Just look at this code snippet from UIInput:
protected void validateValue(FacesContext context,Object convertedValue)
{
boolean empty = convertedValue == null ||
(convertedValue instanceof String
&& ((String)convertedValue).length() == 0);

if (isRequired() && empty)
{
_MessageUtils.addErrorMessage(context, this, REQUIRED_MESSAGE_ID,new Object[]{getId()});
setValid(false);
return;
}

if (!empty)
{
_ComponentUtils.callValidators(context, this, convertedValue);
}

}

This !empty check will prevent any Validator on your component to be called, causing it to always succeed, even when you haven't filled in anything.

So, I think you just have to use a bean validator method.

Uwe Seimet

> So, I think you just have to use a bean validator method.

Thank you for your explanations. Unfortunatley a bean validator also
does not work: The validation method of the bean validator is not called
unless the required attribute of the input field is set. But I cannot set
this attribute because whether input in this field is required or not is
exactly what I need to check with my own validator.

--
-----------------------------------------------------------------------
Dr. Uwe Seimet http://www.seimet.de/

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

Uwe Seimet

> Thank you for your explanations. Unfortunatley a bean validator also
> does not work: The validation method of the bean validator is not called
> unless the required attribute of the input field is set. But I cannot set
> this attribute because whether input in this field is required or not is
> exactly what I need to check with my own validator.

Eventually I was able to solve my problem with a bean validator. I bind
the validator to the checkbox, not to the input field. I can then check
both the checkbox state and the input field content within the validator
and can add the validation error message to the input field messages.
Thanks to all who responded!

--
-----------------------------------------------------------------------
Dr. Uwe Seimet http://www.seimet.de/

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

jkva
Offline
Joined: 2005-04-06
Points: 0

You can also take advantage of the fact that the required attribute accepts EL expressions, like shown here.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%>




















I know it looks crappy, but there are plenty of options to make it nicer. For example, with Facelets you can create a custom function to lookup a component by id.

Functions.java:
public class Functions {
public static UIComponent find(String id) {
FacesContext fc = FacesContext.getCurrentInstance();
return fc.getViewRoot().findComponent(id);
}
}

functions.taglib.xml:



http://www.ordina.nl/facelets/functions

find
nl.ordina.facelets.functions.Functions
javax.faces.component.UIComponent find(java.lang.String)

web.xml:

facelets.LIBRARIES /WEB-INF/functions.taglib.xml

And finally, your web page:

xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:o="http://www.ordina.nl/facelets/functions">

Test







required="#{o:find('form:someBool').value}" />