avalon2砍掉了不少功能(如ms-include,ms-data),騰出空間加了其他更有用的功能。數據驗證就是其中之一。現在avalon2內置的驗證指令是參考之前的oniui驗證框架與jquery validation。
avalon內置驗證規則有
規則 | 描述 |
---|---|
required(true) | 必須輸入的字段。 |
email(true) | 必須輸入正確格式的電子郵件。 |
url(true) | 必須輸入正確格式的網址。 |
date(true或正則) | 必須輸入正確格式的日期。默認是要求YYYY-MM-dd這樣的格式。 |
number(true) | 必須輸入合法的數字(負數,小數)。 |
digits(true) | 必須輸入整數。 |
pattern(正則或true) | 讓輸入數據匹配給定的正則,如果沒有指定,那么會到元素上找pattern屬性轉換成正則再匹配。 |
equalto(ID名) | 輸入值必須和 #id 元素的value 相同。 |
maxlength:5 | 輸入長度最多是 5 的字符串(漢字算一個字符)。 |
minlength:10 | 輸入長度最小是 10 的字符串(漢字算一個字符)。 |
chs(true) | 要求輸入全部是中文。 |
max:5 | 輸入值不能大於 5。 |
min:10 | 輸入值不能小於 10。 |
這些驗證規則要求使用ms-rules指令表示,要求為一個普通的JS對象。
此外要求驗征框架能動起來,還必須在所有表單元素外包一個form元素,在form元素上加ms-validate指令。
<!DOCTYPE html>
<html>
<head>
<title>ms-validate</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<script src="./dist/avalon.js"></script>
<script>
var vm = avalon.define({
$id: "test",
aaa: "",
bbb: '',
ccc: '',
validate: {
onError: function (reasons) {
reasons.forEach(function (reason) {
console.log(reason.getMessage())
})
},
onValidateAll: function (reasons) {
if (reasons.length) {
console.log('有表單沒有通過')
} else {
console.log('全部通過')
}
}
}
})
</script>
</head>
<body ms-controller="test">
<form ms-validate="@validate">
<p><input ms-duplex="@aaa" placeholder="username"
ms-rules='{required:true,chs:true}' >{{@aaa}}</p>
<p><input type="password" id="pw" placeholder="password"
ms-rules='{required:true}'
ms-duplex="@bbb" /></p>
<p><input type="password"
ms-rules='{required:true,equalto:"pw"}' placeholder="再填一次"
ms-duplex="@ccc | change" /></p>
<p><input type="submit" value="submit"/></p>
</form>
</body>
</html>
因此,要運行起avalon2的內置驗證框架,必須同時使用三個指令。ms-validate用於定義各種回調與全局的配置項(如什么時候進行驗證)。ms-duplex用於將單個表單元素及相關信息組成一個Field對象,放到ms-validater指令的fields數組中。ms-rules用於定義驗證規則。如果驗證規則不滿足你,你可以自行在avalon.validators對象上添加。
現在我們可以一下ms-validate的用法。其對應一個對象。
配置項 | 描述 |
---|---|
fields | 框架自行添加,用戶不用寫。為一個數組,放置ms-duplex生成的Field對象。 |
onSuccess | 空函數,單個驗證成功時觸發,this指向被驗證元素this指向被驗證元素,傳參為一個對象數組外加一個可能存在的事件對象。 |
onError | 空函數,單個驗證無論成功與否都觸發,this與傳參情況同上 |
onComplete | 空函數,單個驗證無論成功與否都觸發,this與傳參情況同上。 |
onValidateAll | 空函數,整體驗證后或調用了validateAll方法后觸發;有了這東西你就不需要在form元素上ms-on-submit="submitForm",直接將提交邏輯寫在onValidateAll回調上 |
onReset | 空函數,表單元素獲取焦點時觸發,this指向被驗證元素,大家可以在這里清理className、value |
validateInBlur | true,在blur事件中進行驗證,觸發onSuccess, onError, onComplete回調 |
validateInKeyup | true, 在keyup事件中進行驗證,觸發onSuccess, onError, onComplete回調。當用戶在ms-duplex中使用change debounce過濾器時會失效 |
validateAllInSubmit | true,在submit事件中執行onValidateAll回調 |
resetInFocus | true,在focus事件中執行onReset回調 |
deduplicateInValidateAll | false,在validateAll回調中對reason數組根據元素節點進行去重 |
在上表還有一個沒有提到的東西是如何顯示錯誤信息,這個avalon不幫你處理。但提示信息會幫你拼好,如果你沒有寫,直接用驗證規則的message,否則在元素上找data-message或data-required-message這樣的屬性。
最后給一個復雜的例子:
<!DOCTYPE html>
<html>
<head>
<title>ms-validate</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<script src="./dist/avalon.js"></script>
<script>
var vm = avalon.define({
$id: "test",
firstname: '',
lastname: '',
username: '',
password: '',
confirm_password: '',
email: '',
agree: false,
topic: [],
toggle: false,
validate: {
onError: function (reasons) {
reasons.forEach(function (reason) {
console.log(reason.getMessage())
})
},
onValidateAll: function (reasons) {
if (reasons.length) {
console.log('有表單沒有通過')
} else {
console.log('全部通過')
}
}
}
})
avalon.validators.checked = {
message: '必須扣上',
get: function (value, field, next) {
next(value)
return value
}
}
avalon.validators.selecttwo = {
message: '至少選擇兩個',
get: function (value, field, next) {
next(!vm.toggle || value.length >= 2)
return value
}
}
</script>
</head>
<body ms-controller="test">
<form class="cmxform" ms-validate="@validate" >
<fieldset>
<legend>驗證完整的表單</legend>
<p>
<label for="firstname">名字</label>
<input id="firstname"
name="firstname"
ms-duplex="@firstname"
ms-rules="{required:true}"
data-required-message="請輸入您的名字" >
</p>
<p>
<label for="lastname">姓氏</label>
<input id="lastname"
name="lastname"
ms-duplex="@lastname"
ms-rules="{required:true}"
data-required-message="請輸入您的姓氏"
>
</p>
<p>
<label for="username">用戶名</label>
<input id="username"
name="username"
ms-duplex="@username | change"
ms-rules="{required:true, minlength:2}"
>
</p>
<p>
<label for="password">密碼</label>
<input id="password"
name="password"
type="password"
ms-duplex="@password"
ms-rules="{required:true,minlength:5}"
data-required-message="請輸入密碼"
data-required-message="密碼長度不能小於 5 個字母"
>
</p>
<p>
<label for="confirm_password">驗證密碼</label>
<input id="confirm_password"
name="confirm_password"
type="password"
ms-duplex="@confirm_password | change"
ms-rules="{required:true,equalto:'#password'}"
data-equalto-message="兩次密碼輸入不一致"
>
</p>
<p>
<label for="email">Email</label>
<input id="email"
name="email"
type="email"
ms-duplex="@email"
ms-rules="{email:true}"
data-email-message="請輸入一個正確的郵箱"
>
</p>
<p>
<label for="agree">請同意我們的聲明</label>
<input type="checkbox" class="checkbox" id="agree" name="agree"
ms-duplex-checked="@agree"
ms-rules="{checked:true}"
>
</p>
<p>
<label for="newsletter">我樂意接收新信息</label>
<input type="checkbox" class="checkbox"
id="newsletter"
name="newsletter"
ms-duplex-checked="@toggle"
>
</p>
<fieldset id="newsletter_topics" ms-visible="@toggle" >
<legend>主題 (至少選擇兩個) </legend>
<label for="topic_marketflash">
<input type="checkbox"
id="topic_marketflash"
value="marketflash"
name="topic[]"
ms-duplex="@topic"
ms-rules="{selecttwo:true}"
>Marketflash
</label>
<label for="topic_fuzz">
<input type="checkbox"
id="topic_fuzz"
value="fuzz"
name="topic[]"
ms-duplex="@topic"
ms-rules="{selecttwo:true}"
>Latest fuzz
</label>
<label for="topic_digester">
<input type="checkbox"
id="topic_digester"
value="digester"
name="topic[]"
ms-duplex="@topic"
ms-rules="{selecttwo:true}"
>Mailing list digester
</label>
<label for="topic" class="error" style="display:none">至少選擇兩個</label>
</fieldset>
<p>
<input class="submit" type="submit" value="提交">
</p>
</fieldset>
</form>
</body>
</html>