HTML FORM elements與submit

 

一、EncType有三種屬性值可設定,分別是

application/x-www-form-urlencoded、multipart/form-data、text/plain

(1)、application/x-www-form-urlencoded

表單資料編碼為名稱/值組。這是標準的編碼格式。

當action為get時候,瀏覽器用x-www-form-urlencoded的編碼方式把form數據轉換成一個字串(name1=value1&name2=value2...),

然後把這個字串附加到url後面,用「?」符號分割,加載這個新的url。

當action為post時候,瀏覽器把form數據封裝到http body中,然後發送到server。

如果沒有指定enctype=application/x-www-form-urlencoded時,

則會默認為application/x-www-form-urlencoded。

(2)、multipart/form-data

窗體數據被編碼為一條消息,頁上的每個控件對應消息中的一個部分

但是如果有type=file的話,就要用到multipart/form-data了。

瀏覽器會把整個表單以控件為單位分割,並為每個部分加上Content-Disposition(form-data或者file),

Content-Type(默認為text/plain),name(控件name)等信息,並加上分割符(boundary)。

(3)、text/plain

窗體數據以純文本形式進行編碼,其中不含任何控件或格式字符。

 

以上是大陸那邊的資料,參考看看,

結論為enctype通常都會預設為application/x-www-form-urlencoded

剩下兩個自己套套看吧。主要是字串組合方式不同

 

範例如下:

First name:
Last name:
 
<form action="http://www.w3schools.com/tags/demo_post_enctype.asp" enctype="multipart/form-data" method="post" target="_self">
    First name: <input name="fname" type="text" /><br />
    Last name: <input name="lname" type="text" /><br />
    <input type="submit" value="Submit" />
</form>

 

二、submit方法

submit有三種方法可以傳送表單

後端統一為

public ActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult Index(string file)
{
    return Content(file);
}

 

第一種<input type="submit">、

前端為

<form action="@Url.Action("Index")" method="post" id="myform">
    <input type="text" name="file" value="" />
    <input type="submit" value="sent" />
</form>

 

第二種<input type="image" src="http://www.w3schools.com/html/img_submit.gif">、

前端為

<form action="@Url.Action("Index")" method="post" id="myform">
    <input type="text" name="file" value="" />
    <input type="image" src="http://www.w3schools.com/html/img_submit.gif">
</form>

 

第三種<button type="submit">send</button>、

前端為

<form action="@Url.Action("Index")" method="post" id="myform">
    <input type="text" name="file" value="" />
    <button type="submit">send</button>
</form>

 

三、submit的action方式

1、一個簡單的表單submit會用下列格式

<!DOCTYPE html>
<html>
<body>
    <form action="http://www.w3schools.com/tags/form_submit.asp" method="get">
        First name:<input type="text" name="fname"><br>
        Last name:<input type="text" name="lname"><br><br>
        <input type="submit" value="Send form data!">
    </form>
</body>
</html>

 

2、然而還有另一種方式是利用javascript來做表單提交

<!DOCTYPE html>
<html>
<head>
    <script>
        function formSubmit() {
            document.forms["myForm"].submit();
        }
    </script>
</head>
<body>
    <form name="myForm" action="form_submit.asp" method="get">
        First name: <input type="text" name="fname"><br>
        Last name: <input type="text" name="lname"><br><br>
        <input type="button" onclick="formSubmit()" value="Send form data!">
    </form>
    <p>Notice that the JavaScript in the head section uses the name of the form to specify which form to submit.</p>
</body>
</html>

formSbumit function表示找尋document.forms結構裡名為myForm的form物件,

,不管id或是name都可以找到,然後再執行submit動作。

例如<form id="myForm">或是<form name="myForm">時,

都可以使用document.forms["myForm"]找到

例2:<form id="myFormid" name="myForm">

document.forms["myFormid"]與document.forms["myForm"]都可找到。

 

3、action使用javascript語法

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>submit demo</title>
    <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
    <form action="javascript:alert( 'success!' );">
        <div>
            <input type="text" value="mytest">
            <input type="submit">
        </div>
    </form>
</body>
</html>

 

四、for attribute

"for" attribute 是用來增加表單的易用性,

讓滑鼠點到標題也可以讓鍵盤游標留在textbox要輸入的欄位上

 
<!DOCTYPE html>
<html>
<body>
    <form>
        <label for="nameid">Name</label>
        <input type="text" name="myname" id="nameid"><br>
    </form>
</body>
</html>

 

五、form其他屬性參考

Attribute Description
accept-charset Specifies the charset used in the submitted form (default: the page charset).
action Specifies an address (url) where to submit the form (default: the submitting page).
autocomplete Specifies if the browser should autocomplete the form (default: on).
enctype Specifies the encoding of the submitted data (default: is url-encoded).
method Specifies the HTTP method used when submitting the form (default: GET).
name Specifies a name used to identify the form (for DOM usage: document.forms.name).
novalidate Specifies that the browser should not validate the form.
target Specifies the target of the address in the action attribute (default: _self).

参考資料:

關於application/x-www-form-urlencoded等字符編碼的解釋說明

HtmlForm.Enctype 屬性

 

六、event.preventDefault();的使用時機

先舉一個範例

前端為

<form id="myform">
    <input type="text" name="file" value="" />
    <input type="submit" value="send" />
</form>

<div id="mydiv">

</div>

@section scripts{
    <script>
        $("#myform").submit(function myfunction(event) {
            $.ajax({
                url: '@Url.Action("Index")',
                type: 'POST',
                data: $('#myform').serialize(),
                success: function (data) {
                    $("#mydiv").append("<p>" + data + "</p>");
                }
            });
        });
    </script>
}

後端為

public ActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult Index(string file)
{
    return Content(file);
}

實際操作時,你卻會發現結果會如下圖依序發生

明明form元素的屬性沒特別使用action與method屬性,

而jQuery的submit事件只是用來偵測當<input type="submit" value="send" />

按下去時所觸發的submit事件,然後在事件裡做自已想要做的事,

當成功時會秀出剛輸入的值,卻只是短暫出現又消失了。

這很奇怪,根本就是一椿靈異事件,WHY?

為了讓問題更容易被顯現出來,先將前端改成如下(黃底標示)

<form id="myform" action="@Url.Action("Index")" method="post">
    <input type="text" name="file" value="" />
    <input type="submit" value="send" />
</form>

<div id="mydiv">

</div>

@section scripts{
    <script>
        $("#myform").submit(function myfunction(event) {
            $.ajax({
                url: '@Url.Action("Index")',
                type: 'POST',
                data: $('#myform').serialize(),
                success: function (data) {
                    $("#mydiv").append("<p>" + data + "</p>");
                }
            });
        });
    </script>
}

再重新執行一次,中斷點下在「return Content(file);」那邊,

你會發現「return Content(file);」會連續跑兩次,

第一次是跑jQuery submit事件的request,所以你會看到如下成果

而第二次是form元素所預設的動作,回傳純文字

經由此結果可回推先前範例的靈異現象,雖然form元素沒有明確指定action與method,

但submit會有預設動作,其動作為當按下<input type="submit">按紐時,

會將表單資料往後端送,然後再把剛輸入的欄位資料給清空(應具有該頁面重讀一次特性)。

正確來說應該是只要在form表單範圍裡有觸發submit事件,就會將表單資料往後端送,

如下範例在form表單裡的button沒有特別指定<button type="submit"></button>,但也會觸發submit事件。

前端為

<form id="myform">
    <input type="text" name="file" value="" />
    <button id="btnUpLoad">上傳</button>
</form>

<div id="mydiv">
</div>

@section scripts{
    <script>
        $("#myform").submit(function myfunction(event) {
            $.ajax({
                url: '@Url.Action("Index")',
                type: 'POST',
                data: $('#myform').serialize(),
                success: function (data) {
                    $("#mydiv").append("<p>" + data + "</p>");
                }
            });
        });
    </script>
}

後端為

public ActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult Index(string file)
{
    return Content("OK");
}

 

那這靈異現象要如何解決呢?因為程式本意為使用ajax post來替代submit預設動作,

所以請在submit事件被觸發時做完ajax podt後,記得加入event.preventDefault();把submit預設動作給關掉即可。

<form id="myform">
    <input type="text" name="file" value="" />
    <input type="submit" value="send" />
</form>

<div id="mydiv">

</div>

@section scripts{
    <script>
        $("#myform").submit(function myfunction(event) {
            $.ajax({
                url: '@Url.Action("Index")',
                type: 'POST',
                data: $('#myform').serialize(),
                success: function (data) {
                    $("#mydiv").append("<p>" + data + "</p>");
                }
            });
            event.preventDefault();
        });
    </script>
}

而event.preventDefault();要加至事件裡的開頭或最後都可(習慣是加在最後面)。

 

七、form裡面包含可用的elements

1、select-option

<!DOCTYPE html>
<html>
<body>
    <form action=@Url.Action("Index") method="post">
        <select name="cars">
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
            <option value="fiat" selected>Fiat</option>
            <option value="audi">Audi</option>
        </select>
        <input type="submit" value="submit" />
    </form>
</body>
</html>

後端為

[HttpPost]
public ActionResult Index(string cars)
{
    return Content(cars);
}

 

2、類似VB.NET groupbox功能的<fieldset>

Personal information: Name:
E-mail:
Date of birth:
 
<!DOCTYPE html>
<html>
<body>
    <form action=@Url.Action("Index") method="post">
        <fieldset>
            <legend>Personal information:</legend>
            Name: <input type="text" size="30" name="Name"><br>
            E-mail: <input type="text" size="30" name="Email"><br>
            Date of birth: <input type="text" size="10" name="Date">
        </fieldset>
        <input type="submit" name="name" value="submit" />
    </form>
</body>
</html>

後端為

[HttpPost]
public ActionResult Index(string Name, string Email, string date)
{
    return Content(Name + " " + Email + " " + date);
}

注意:後端接收的名稱可不分大小寫

 

3、datalist-option

JS Bin

<!DOCTYPE html>
<html>
<body>
    <form action=@Url.Action("Index") method="post">
        <input list="browsers" name="browser">
        <datalist id="browsers">
            <option value="Internet Explorer">
            <option value="Firefox">
            <option value="Chrome">
            <option value="Opera">
            <option value="Safari">
        </datalist>
        <input type="submit">
    </form>
</body>
</html>

後端為

[HttpPost]
public ActionResult Index(string browser)
{
    return Content(browser);
}

注意datalist-option與select-option不同的地方為

datalist-option除了提供選項給USER選擇外,也可允許USER自訂輸入資料,

而select-option只能由預設提供的選項來選擇而已。

 

4、keygen

Username:
Encryption:  
 
<!DOCTYPE html>
<html>
<body>
    <form action=@Url.Action("Index") method="post">
        Username:
        <input type="text" name="user">
        <br />
        Encryption:
        <keygen name="security">
        <br />
        <input type="submit">
    </form>
</body>
</html>

後端為

[HttpPost]
public ActionResult Index(string user,string security)
{
    return Content(user +" "+ security);
}

 

5、output

0 100 + =  

 
<!DOCTYPE html>
<html>
<body>
    <form action=@Url.Action("Index") method="post"
                  oninput="x.value=parseInt(a.value)+parseInt(b.value)">
        0
        <input type="range" id="a" name="a" value="50">
        100 +
        <input type="number" id="b" name="b" value="50">
        =
        <output name="x" for="a b"></output>
        <br><br>
        <input type="submit">
    </form>
</body>
</html>

後端為

[HttpPost]
public ActionResult Index(string a,string b)
{
    return Content(a +" "+ b);
}

 

參考資料:

HTML Form Elements