おまけ。
複数のフィールドで、日付を入力したいとかって言う
よくある 面倒な 要望に対応するためのバリデータ。
package examples.jsf.validator;
import java.util.Calendar;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import org.seasar.jsf.util.MessageUtil;
import org.seasar.jsf.util.UIComponentUtil;
/**
* @author cero-t
*
*/
public class S2MultiFieldCalendarValidator extends
S2MultiSubmittedValueValidator {
public static final String ARGS_MESSAGE_ID = "examples.jsf.validator.S2MultiFieldCalendarValidator.ARGS";
public static final String LENIENT_MESSAGE_ID = "examples.jsf.validator.S2MultiFieldCalendarValidator.LENIENT";
protected void doValidate(FacesContext context, UIComponent component,
Object value, UIComponent[] targetComponents, Object[] targetValues)
throws ValidatorException {
if (targetValues == null) {
return;
}
if (targetValues.length < 2) {
Object[] args = { UIComponentUtil.getLabel(component) };
throw new ValidatorException(MessageUtil.getErrorMessage(
ARGS_MESSAGE_ID, args));
}
Calendar calendar = Calendar.getInstance();
calendar.setLenient(false);
calendar.set(Calendar.YEAR, getAsInt(targetValues[0]));
calendar.set(Calendar.MONTH, getAsInt(targetValues[1]) - 1);
calendar.set(Calendar.DATE, getAsInt(targetValues[2]));
try {
calendar.getTime();
} catch (IllegalArgumentException ex) {
Object[] args = { UIComponentUtil.getLabel(component) };
FacesMessage message = MessageUtil.getErrorMessage(
LENIENT_MESSAGE_ID, args);
throw new ValidatorException(message);
}
}
private int getAsInt(Object o) {
if (o == null) {
return 0;
}
if (o instanceof Integer) {
return ((Integer) o).intValue();
}
return Integer.parseInt(o.toString());
}
}
HTMLは、こんな感じ。
diconは省略。
<select id="year" m:value="#{userInfoDto.birthdayYear}" m:label="生年月日">
<span m:inject="s:validator"
m:binding="#{multiFieldCalendarValidator}"
m:targetId="year,month,day"/>
<option value="1974">1974</option>
<option value="1975">1975</option>
<option value="1976">1976</option>
<option value="1977">1977</option>
<option value="1978">1978</option>
<option value="1979">1979</option>
<option value="1980">1980</option>
<option value="1981">1981</option>
<option value="1982">1982</option>
</select>年
<select id="month" m:value="#{userInfoDto.birthdayMonth}">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>月
<select id="day" m:value="#{userInfoDto.birthdayDay}">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>日
<span m:inject="h:message" m:for="year"/>MultiSubmittedValueValidatorを継承しているので、
HTML上では、年にValidatorを掛けても正常動作します。
MultiFieldValidatorを継承するように変更しても
(ソースの他の部分を変更せずに)そのまま使えるけど、
HTML上では、日にValidatorを掛けなきゃいけません。