2015年7月21日 星期二

AJAX傳輸formaction

最近寫專案的關係,去碰html5的 submit button 的 form action 在以前,要兩個 submit button 分別傳不同的action,若是不考慮 js 的話,我第一個想到下面這方法。
<form action="/submit_page" onsubmit="return false">
	<input type="submit" name="s" value="submit1" />
	<input type="submit" name="s" value="submit2" />
</form>
當你點 submit1 button 時候,傳過去的request 會是/submit_page?s=submit1;若是第二個button,則會是/submit_page?s=submit2
之後再在後台根據request param s 來判斷即可……
現在html5中,submit button 多了formaction這個attribute可以用
<form action="/submit_page" onsubmit="return false">
	<input type="submit" value="submit1" />
	<input type="submit" value="submit2" formaction="/another_submit_page" />
</form>
點擊第二個submit button就會連到頁面「/another_submit_page」,的確是很大的福音呢……如果是就好了……


這東西很方便沒錯,但問題是js啊……
在現在這時代,AJAX已經如同早餐的一杯飲料、冷凍庫的冰塊、料理的調味料一樣重要、一樣常見了。
而form的submit若是沒有formaction的話,倒還沒什麼關係,但有AJAX的話就有問題了。

目前chrome版本已經到46了;IE11;Firefox 39;Opera 30……
雖然我電腦沒用Opera,但Event只有firefox能讀到formaction的值…… 以下面的form為例:
<form action="/submit_page" onsubmit="return false">
	<input type="submit" value="submit1" />
	<input type="submit" value="submit2" formaction="/another_submit_page" />
</form>
firefox可以這樣讀取
document.querySelector("form").addEventListener("submit", function(e){
	var form   = e.target;
	var input  = e.explicitOriginalTarget;
	var action = input.formAction || form.action;
	
	//TODO AJAX send request to "action"
}, true);
AJAX的code是另一回事,就不屬於我的討論範圍了
而其他瀏覽器,因為沒有 Event.prototype.explicitOriginalTarget (其實這是一個getter variable,所以可能要用 __lookupGetter__來找)
我個人的方法是,既然沒有,那我就強制改寫form的action,然後當form submit時,再根據form action來決定AJAX的request URL
// 強制設定普通的 submit button的formaction
[].slice.call(document.querySelectorAll("input:not([formaction])")).forEach(function(input){
	input.formAction = input.form.action
});

// submit button click 時,變更 form action
[].slice.call(document.querySelectorAll("[type=submit]")).forEach(function(input){
	input.addEventListener("click", function(e){
		document.querySelector("#result").innerHTML = (this)
		this.form.action = this.formAction
		console.log(this)
	}, true)
})

document.querySelector("form").addEventListener("submit", function(e){
	//TODO AJAX send request to "form.action"
}, true);
將ff版和其他瀏覽器的合併後就如下
if(!Event.prototype.__lookupGetter__("explicitOriginalTarget")){
	[].slice.call(document.querySelectorAll("input:not([formaction])")).forEach(function(input){
		input.formAction = input.form.action
	});

	[].slice.call(document.querySelectorAll("[type=submit]")).forEach(function(input){
		input.addEventListener("click", function(e){
			document.querySelector("#result").innerHTML = (this)
			this.form.action = this.formAction
		}, true)
	})
}

document.querySelector("form").addEventListener("submit", function(e){
	var form   = e.target;
	var input  = e.explicitOriginalTarget;
	var action = form.action
	if(input && input.formAction){
		action = input.formAction
	}
	
	//TODO AJAX send request to "action"
}, true);
最後說一下,我個人是很同意《YOU MIGHT NOT NEED JQUERY》,但……$("Elements Selector").each(function())[].slice.call(document.querySelectorAll("Elements Selector")).forEach(function(element, index, array){})的清晰度和簡易度也差太多了吧……

沒有留言:

張貼留言