在 Web 開發中,表單驗證是確保資料完整性的關鍵環節。傳統的提交後驗證體驗較差,而 Ajax 即時驗證能在使用者輸入時即時回饋,大幅提升使用體驗。本文將詳細介紹如何結合 JavaScript、伺服器端程式(以 Ruby on Rails 為例)實現一個完整的即時表單驗證功能。
優雅降級是專業開發的基本素養。使用 <noscript> 標籤提示使用者啟用 JS,並預設隱藏提交按鈕,僅在 JS 啟用時透過腳本顯示:
<noscript>
<div style="color:red">您的瀏覽器不支援 JavaScript,部分功能無法使用</div>
</noscript>
<div id="js_support" style="display:none">
<p id="pSubmit">
<input type="submit" name="registerform" value="註冊" onclick="return submitform();" />
</p>
</div>
<script type="text/javascript">
$("js_support").style.display = "block";
</script>
在輸入框上同時綁定 onfocus 和 onkeyup 事件,確保使用者聚焦時與輸入時都能觸發驗證:
<input type="text" class="textbox" onfocus="checkLogin(this);" onkeyup="checkLogin(this);" style="width:120px;" />
此處使用了封裝好的 bp.js 函式庫處理 XMLHTTPRequest。驗證流程分為三個階段:
validatePath)function checkLogin(node) {
clearError();
if (bp.String.trim(node.value) != "") {
var url = "/test/response_validate";
var params = [];
params["command"] = "logincheck";
params["login"] = encodeURI(bp.String.trim(node.value));
// 客戶端格式驗證
var v = validatePath("login", params["login"]);
if (v == "") {
// 發送 Ajax 請求
bp.Io.XhrGet({
url: url,
mimeType: "text/json",
params: params,
load: function(type, data, e) {
if (data == true) {
// 帳號已存在
document.getElementById("valstatus").innerHTML = '登錄名已存在';
document.getElementById("loginValidate").className = "icon_cross";
node.className = "input_error";
loginValid = false;
} else {
// 帳號可用
loginError = "";
document.getElementById("loginValidate").className = "icon_ok";
node.className = "textbox";
loginValid = true;
}
},
error: function(type, data, e) {}
});
} else {
// 格式不符
loginError = document.getElementById("valstatus").innerHTML = v;
document.getElementById("loginValidate").className = "icon_cross";
node.className = "input_error";
loginValid = false;
}
} else {
// 輸入為空
loginError = validatePath("login", "");
document.getElementById("loginValidate").className = "";
node.className = "textbox";
}
}
後端接收參數,執行查詢邏輯,回傳 JSON 格式的布林值(true 代表已存在,false 代表可用)。這裡以簡單的字串比對為例,實際專案中應查詢資料庫:
def response_validate
if params[:login]
name = params[:login]
puts name
if name == "aaaaaa"
@value = true
else
@value = false
end
render :partial => 'show_info'
end
end
備註: show_info 部分視圖僅需輸出 <%= @value %> 即可。Java、PHP 等平台同理,只需輸出 true 或 false 字串。
onkeyup 中加入 setTimeout 防抖,避免頻繁請求壓垮伺服器。error 回呼,網路異常時給予使用者友善提示。fetch API 或 axios 替代封裝庫,配合 async/await 寫法更清晰。