mrmu 設計工作室

WordPress 網站架設、使用者經驗、互動介面研究

  • 服務與作品
  • 關於mrmu
  • 網站架設

表單提交(submit)時使用preventDefault可能產生的問題

2011-04-12 by audi_lu 3 Comments


在表單內的任一輸入框按下Enter後,預設情況下表單會自動提交,若使用preventDefault阻止後,表單將從此不能Submit,怎麼辦?

一般我們設計HTML表單後,若在Form內的文字框按下Enter,預設會觸發Submit事件,造成表單提交。但若有某些文字框我們有特別的用途,希望它按下Enter後不要Submit表單,而是去做一些特定的動作,此時我們可以先使用preventDefault,之後再讓表單可以被Submit嗎?

舉例來說,假設我們設計了一個表單,裡面有一個可輸入「代號」的文字框,以及一個會出現該代號對應的「名稱」文字框。

這時需求要的情境是,輸入代號後,按下Enter,名稱文字框就會立即出現該代號對應的名稱,經過使用者判斷確認這是他要選的代號及名稱,才按下submit鍵送出結果。

我們先做form的設計,如下:

<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>

好的,接著我們用jQuery來撰寫「在代號框輸入數值後會自動出現對應名稱」的程式碼:

<script type="text/javascript">
	$(function(){
		// 偵測若在代號框輸入值後,按下Enter,就填進對應的名稱
		$('#code').keydown(function(e){
			if (e.keyCode == '13') // Enter鍵值為13
			{
			// 觸發填值的動作,在此省略
			}
		});
	});
</script>

此時問題就會發生了,因為在還沒執行到填值時,我們的Enter動作早已先觸發了submit鍵的click動作,對應名稱都還沒出現,表單就被提交了。
這時也許你會想到要使用preventDefault()去阻擋預設的提交動作:

<script type="text/javascript">
	$(function(){
        	// 偵測若在代號框輸入值後,按下Enter,就填進對應的名稱
        	$('#code').keydown(function(e){
			if (e.keyCode == '13') // Enter鍵值為13
			{
			// 觸發填值的動作,可能用get或load等ajax取值...
			}
        	});

		// 表單的submit都會進來這兒
		$('#submit').click(function(e){
			e.preventDefault(); // 成功阻擋Enter的submit動作!
		});
	});
</script>

是的,成功阻擋了submit,但是若您手動去按提交鍵會發現submit動作也被擋了,再也提交不出表單了XD。於是有人會問,如何在使用過e.preventDefault後,再一次讓submit復活呢(reenable submit)!?? 唉,我也沒試出來XD,不過在此可以使用一個workaround的方式解決。

重新解讀我們想完成的事情就是–希望submit事件不要在代號框取得focus時會return true,讓它好好的做它該做的事:去把名稱填好。了解這樣的方式後,解決方式幾乎就呼之欲出了:

<script type="text/javascript">
	$(function(){
		// 用來判斷是否submit的flag
		var fSubmit = false;

		// 偵測若在代號框輸入值後,按下Enter,就填進對應的名稱
		$('#code').keydown(function(e){
			if (e.keyCode == '13') // Enter鍵值為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
		});
	});
</script>

如此就可以滿足一開始所提的需求。
至於如何在使用過preventDefault後再次submit呢?期待各位先進可以分享,感謝!

Filed Under: 網站架設 Tagged With: jQuery, 網站設計

Comments

  1. HeChien says

    2012-08-21 at 18:23:52

    $(‘form’).submit();

    回覆
  2. sheephead says

    2012-03-06 at 22:24:22

    你好喔
    ㄏ 你們的文章寫得很讚
    不過就這個範例而言應該不用那麼麻煩

    只要在按下ENTER裡面的判斷最後加上e.preventDefault();就可以了
    不用特意去處理submit那一段程式碼。

    回覆

Trackbacks

  1. jQuery – event.preventDefault() vs. e.stopPropagation() vs. return false | 烏龜田表示:
    2013-05-0412:37:56

    […] 是避免原本的動作執行,可參考jQuery官方的API documentation 或是以表單提交爲範例 […]

    回覆

發佈回覆給「jQuery – event.preventDefault() vs. e.stopPropagation() vs. return false | 烏龜田」的留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料。

近期文章

  • 2017 COSCUP WordPress 社群議程:WordPress 開發大小事
  • Webpack 實作入門2:打包 CSS / SCSS 與 加入 Bootstrap
  • Webpack 實作入門1:寫給 “非Node.js開發者” 的教學
  • WordPress 4.7 重磅發表,快來了解有哪些重大更新!
  • 東京自由行之 WordCamp Tokyo 2016
  • 愚人節玩笑成真?WordPress 發表 Node.js 及 React.js 打造的後台應用 – Calypso
  • 使用Git、Composer、Sublime Text進行WordPress專案開發
  • WordPress自訂模組(widget)及顯示版位
  • 新手路跑賽心得及賽前準備 – 臺北渣打公益路跑賽12.5km
  • WordPress 10th Anniversary – WP10週年歡慶小聚

分類

  • CSS (2)
  • JavaScript (8)
  • WordPress (26)
  • 人生哲學 (3)
  • 公告 (9)
  • 活動聚會 (10)
  • 生活記事 (29)
  • 網站架設 (78)
  • 網路行銷 (14)
  • 金工 (134)
  • 開課教學 (29)

Copyright © 2019 · Genesis Sample Theme on Genesis Framework · WordPress · Log in