允許使用者輸入幾乎是每個系統都需要的功能,為了確保資料內容或格式的正確性,通常會加上一些資料驗證規則來確保使用者輸入是符合預期的,以下介紹幾種 zk 的輸入驗證方法。
每個輸入元件都支援 constraint
屬性,你可以指定許多內建的驗證規則。例如,先前所提的英雄列表範例中,我不允許英雄的名字為空字串。
我可以這麼做:
<textbox id="newNameBox" ... constraint="no empty: 不能為空字串"/>
可指定多個規則:
<datebox constraint="no empty, no future: now or never"/>
可自定 regular expression 來驗證:
<textbox constraint="/.+@.+\.[a-z]+/: e-mail address only"/>
ZK 內建 constraint 是在瀏覽器端由 JavaScript 實作來驗證。
如果內建規則不能滿足,例如要驗證的是自訂的業務邏輯,則可自行實作 Constraint
:
public class EvenNumberConstraint implements Constraint {
public void validate(Component comp, Object value) throws WrongValueException {
if (value != null && Integer.valueOf(value.toString()).intValue() % 2 == 1)
throw new WrongValueException(comp, "Only even numbers are allowed, not "+value);
}
}
然後指定給某個輸入元件:
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<textbox constraint="${c:new('quickstart.validate.EvenNumberConstraint')}"/>
上面這個例子,我用了ZK 內建的 tag library 來產生一個新物件。
如果你已經用了 client端 constraint,又需要在伺服器驗證,就可用 onChange
傾聽器做驗證:
public class ValidateComposer implements Composer {
@Override
public void doAfterCompose(Component comp) throws Exception {
if (comp instanceof Textbox){
comp.addEventListener(Events.ON_CHANGE, event -> {
Textbox box = (Textbox) comp;
if (box.getValue().length() <= 1){
throw new WrongValueException(box, "至少要超過一個字");
}
});
}
}
}
WrongValueException
,傳入的字串就是會顯示在畫面上的錯誤訊息box
傳進 WrongValueException
,錯誤訊息才會顯示在 <textbox>
上用 apply 套在元件上:
<textbox constraint="no empty" apply="quickstart.validate.ValidateComposer"/>
這是另一種實作控制器的方法:只實作 Composer
介面,覆寫 doAfterCompose()
即可。通常用在你要對元件加上客製化行為時,而實作在一個特定的控制器可以讓你很容易地套用在不同元件上,又可以輕易地拿掉。
另一種做法就是繼承 ZK 內建的驗證類別,然後加上自訂的驗證規則:
public class YouthConstraint extends SimpleConstraint {
/* 初始化念間規則 */
public YouthConstraint(int flags) {
super(flags);
}
/* 自訂驗證規則 */
@Override
public void validate(Component comp, Object value) throws WrongValueException {
if (value != null && Integer.valueOf(value.toString()).intValue() >=18)
throw new WrongValueException(comp, "必須小於 18");
}
}
在控制器中指定要用的驗證規則:
public class YouthValidationComposer implements Composer {
@Override
public void doAfterCompose(Component component) throws Exception {
if (component instanceof Intbox){
Intbox box = (Intbox) component;
box.setConstraint(new YouthConstraint(SimpleConstraint.NO_NEGATIVE+
SimpleConstraint.END_AFTER));
}
}
}
套在元件上時,要加上一個空的 onChange
傾聽器,讓元件把值送到伺服器:
<intbox apply="quickstart.validate.YouthValidationComposer" onChange=""/>
參考: