iT邦幫忙

2021 iThome 鐵人賽

DAY 12
1
Modern Web

ZK 30天速成系列 第 12

使用者輸入驗證

  • 分享至 

  • xImage
  •  

允許使用者輸入幾乎是每個系統都需要的功能,為了確保資料內容或格式的正確性,通常會加上一些資料驗證規則來確保使用者輸入是符合預期的,以下介紹幾種 zk 的輸入驗證方法。

client端驗證: constraint

內建規則

每個輸入元件都支援 constraint 屬性,你可以指定許多內建的驗證規則。例如,先前所提的英雄列表範例中,我不允許英雄的名字為空字串。
https://ithelp.ithome.com.tw/upload/images/20210927/20050621kiDUj954nZ.jpg

我可以這麼做:

<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

如果內建規則不能滿足,例如要驗證的是自訂的業務邏輯,則可自行實作 Constraint
https://ithelp.ithome.com.tw/upload/images/20210927/20050621yTGPPxkg0x.jpg

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 傾聽器做驗證:
https://ithelp.ithome.com.tw/upload/images/20210927/20050621w4XVywBytQ.jpg

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() 即可。通常用在你要對元件加上客製化行為時,而實作在一個特定的控制器可以讓你很容易地套用在不同元件上,又可以輕易地拿掉。

繼承預設 SimpleConstraint

另一種做法就是繼承 ZK 內建的驗證類別,然後加上自訂的驗證規則:
https://ithelp.ithome.com.tw/upload/images/20210927/20050621zx9Ps89w8C.jpg

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=""/>

參考:


上一篇
英雄列表範例:修改英雄
下一篇
資料驅動的元件
系列文
ZK 30天速成30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言