Wicket で自作する重複チェックバリデータを TextField だけでなく、
DropDownChoice や RadioChoice , CheckBoxMultipleChoice でも考えた時、
悩んだあげくに画面表示している文字列を返すメソッドとIDを返す
メソッドを約束するインターフェースを使用することにした。
メソッド名もしくはフィールド名の付与を約束させてリフレクションで
バリデーション値を受け取る方法も考えたがタイプセーフでなくなるので諦めた。
public interface ChoiceValidatable{
public String idString();
public String display();
}
public class DuplicateChoiceValidator<T extends ChoiceValidatable>
extends AbstractValidator<T>{
private Map<String,Object> checkMap;
public DuplicateChoiceValidator(Map<String,Object> validatorCheckMap){
this.checkMap = validatorCheckMap;
}
@Override
protected void onValidate(IValidatable<T> validatable){
ChoiceValidatable choice = validatable.getValue();
if (this.checkMap.containsKey(choice.idString())){
Map<String,Object> vmap = new HashMap<String,Object>();
vmap.put("DupliValue",choice.display());
error(validatable,"DuplicateInput",vmap);
}else{
this.checkMap.put(choice.idString(),choice.display());
}
}
}
----------------------------
DropDownChoice を使う時、、、
Map<String,Object> validatorCheckMap = new HashMap<String,Object>();
protected Map<String,Object> getValidatorCheckMap(){
return this.validatorCheckMap;
}
Form<Void> form = new Form<Void>("form");
final DropDownChoice<ColorChoice> data1 = new DropDownChoice<ColorChoice>(
"data1",new Model<ColorChoice>(),getColorChoiceList()
,new ChoiceRenderer<ColorChoice>("display","idString")
);
data1.setRequired(true);
data1.add(new DuplicateChoiceValidator<ColorChoice>(getValidatorCheckMap()));
form.add(data1);
final DropDownChoice<ColorChoice> data2 = new DropDownChoice<ColorChoice>(
"data2",new Model<ColorChoice>(),getColorChoiceList()
,new IChoiceRenderer<ColorChoice>(){
@Override
public Object getDisplayValue(ColorChoice c){ return c.display(); }
@Override
public String getIdValue(ColorChoice c,int index){ return c.idString(); }
}
);
data2.setRequired(true);
data2.add(new DuplicateChoiceValidator<ColorChoice>(getValidatorCheckMap()));
form.add(data2);