表單提交(submit)時使用preventDefault可能產生的問題
| 2011/04/12 | 1 則迴響
在表單內的任一輸入框按下Enter後,預設情況下表單會自動提交,若使用preventDefault阻止後,表單將從此不能Submit,怎麼辦?
一般我們設計HTML表單後,若在Form內的文字框按下Enter,預設會觸發Submit事件,造成表單提交。但若有某些文字框我們有特別的用途,希望它按下Enter後不要Submit表單,而是去做一些特定的動作,此時我們可以先使用preventDefault,之後再讓表單可以被Submit嗎?
舉例來說,假設我們設計了一個表單,裡面有一個可輸入「代號」的文字框,以及一個會出現該代號對應的「名稱」文字框。
這時需求要的情境是,輸入代號後,按下Enter,名稱文字框就會立即出現該代號對應的名稱,經過使用者判斷確認這是他要選的代號及名稱,才按下submit鍵送出結果。
我們先做form的設計,如下:
[code lang=”html”]
<form id=”new” action=”” method=”POST”>
<input type=”text” id=”code” name=”code”> <!– 代號輸入框 –>
<input type=”text” id=”name” name=”name”> <!– 名稱出現框 –>
<input type=”submit” id=”submit” value=”提交” />
</form>
[/code]
好的,接著我們用jQuery來撰寫「在代號框輸入數值後會自動出現對應名稱」的程式碼:
[code lang=”javascript”]
$(function(){
// 偵測若在代號框輸入值後,按下Enter,就填進對應的名稱
$(‘#code’).keydown(function(e){
// Enter鍵值為13
if (e.keyCode == ’13’) {
// 觸發填值的動作,在此省略
}
});
});
[/code]
此時問題就會發生了,因為在還沒執行到填值時,我們的Enter動作早已先觸發了submit鍵的click動作,對應名稱都還沒出現,表單就被提交了。
這時也許你會想到要使用preventDefault()去阻擋預設的提交動作:
[code lang=”javascript”]
$(function(){
// 偵測若在代號框輸入值後,按下Enter,就填進對應的名稱
$(‘#code’).keydown(function(e){
// Enter鍵值為13
if (e.keyCode == ’13’) {
// 觸發填值的動作,可能用get或load等ajax取值…
}
});
// 表單的submit都會進來這兒
$(‘#submit’).click(function(e){
e.preventDefault(); // 成功阻擋Enter的submit動作!
});
});
[/code]
是的,成功阻擋了submit,但是若您手動去按提交鍵會發現submit動作也被擋了,再也提交不出表單了XD。於是有人會問,如何在使用過e.preventDefault後,再一次讓submit復活呢(reenable submit)!?? 唉,我也沒試出來XD,不過在此可以使用一個workaround的方式解決。
重新解讀我們想完成的事情就是–希望submit事件不要在代號框取得focus時會return true,讓它好好的做它該做的事:去把名稱填好。了解這樣的方式後,解決方式幾乎就呼之欲出了:
[code lang=”javascript”]
$(function(){
// 用來判斷是否submit的flag
var fSubmit = false;
// 偵測若在代號框輸入值後,按下Enter,就填進對應的名稱
$(‘#code’).keydown(function(e){
// Enter鍵值為13
if (e.keyCode == ’13’) {
// 觸發填值的動作,可能用get或load等ajax取值
}
}).focus(function(){ // 代號框取得focus,這時擋下所有的submit事件
fSubmit = false;
}).blur(function(){
fSubmit = true; //代號框失去focus,這時允許submit
})
// 表單的submit都會進來這兒
$(‘form’).submit(function(e){
return fSubmit; // 傳回true就會submit,傳回false就表示不作submit
});
});
[/code]
如此就可以滿足一開始所提的需求。
至於如何在使用過preventDefault後再次submit呢?期待各位先進可以分享,感謝!
分類:JavaScript技巧, 網站設計
本文作者是Audi Lu
1 則留言
你好喔
ㄏ 你們的文章寫得很讚
不過就這個範例而言應該不用那麼麻煩
只要在按下ENTER裡面的判斷最後加上e.preventDefault();就可以了
不用特意去處理submit那一段程式碼。