介绍
这段时间做了个后台的前端项目。说实话,之前并没有做过后台的项目。在做了后台项目后,发现最重要的是要熟练掌握表单相关的技术。这篇文章将我所做的后台项目中用到的表单相关的知识做一个总结,也算是一种积累吧。:)
一个简单的表单示例
下面是一个简单的表单示例:
<form id="main-form" action="http://somesite.com/prog/adduser" method="post">
<label for="name">姓名: </label>
<input type="text" name="name" id="name"><br>
<label>
性别:
<input type="radio" name="sex" value="Male">男
<input type="radio" name="sex" value="Female">女<br>
<label>
<input type="submit" value="Send"> <input type="reset">
</form>
页面如图所示:
当我们点击send按钮时,就能向服务器端发送表单。点击重置按钮时,input中的value值将会是我们设置的默认值。
form的action属性值为服务端处理我们提交的表单的URI。
method是表单提交的方式。
input标签是表单中的控件,用户在input中输入的值,或者用户选择了某个radio选项的值就是这个控件的value值。当提交表单时,input中的name和value值编码后传给服务器端,服务器端解码后根据name和value键值对获取用户提交的信息。
表单提交的过程
成功控件
成功控件是能被提交给服务端的控件,每个成功控件都有其name已经value值,以被作为form数据的一部分传给服务器端。一个成功控件必须在form标签之中,并且有name值。
此外,成功控件还需满足以下条件:
- 控件不能设置为disabled。
- 如果form包含多个提交按钮,只有被点击的提交按钮才是成功控件。
- 被选中的checkbox才算成功控件。
- 被选中的radio才算成功控件。
- select选项,被选中的option才是成功控件,如果没有option被选中,那么这个select不是成功控件,将不被提交。
- 包含了文件的file控件才是成功控件。
注意:如果控件的display属性被设置为none,控件仍然可以是成功的。
提交表单
表单提交可以分为以下几步:
- 1、验证成功的控件,如上文所诉。
- 2、创建表单数据集,由成功控件的name和value组成的键值对序列。
- 3、编码表单数据集,编码方式由form元素的enctype属性来指定。
- 4、提交编码后的表单数据集。
对多个提交按钮,做不同提交任务的处理
我们经常会碰到这样的需求,一个页面中有多个不同的按钮,点击按钮时服务端做不同的处理。此时我们改如何处理呢?
一种方式是可以给提交按钮设置不同的name,服务端通过判断name来判断用户点击了哪个按钮,然后做相应的处理。另一种方式是给提交按钮设置相同的name,不同的value,服务端通过判断value值来判断用户点击了哪个按钮。
以上两种方式将判断的工作交给了服务端。对于前端,我们可以用ajax的方式提交表单来实现多个提交按钮的处理。用ajax提交的另一个好处是可以防止页面刷新或者跳转到action指定的页面。
如果用jQuery,我们可以这么提交:
$("#main-form").on("submit", function(e) {
e.preventDefault();
$.post(this.action, $(this).serialize());
});
用jQuery,如果想上传部分表单,我们可以这么提交
<div id="divCustomerInfo">
<p>名称: <input type="text" name="CustomerName" /></p>
<p>电话: <input type="text" name="CustomerTel" /></p>
</div>
$("#btnId").click(function(){
$.ajax({
url: "test.htm",
type: "POST",
data: $('#divCustomerInfo :text').fieldSerialize(),
success: function(responseText){
alert(responseText);
}
});
return false;
});
利用H5的FormData对象,我们可以这么提交:
document.getElementById("main-form").onsubmit = function(e) {
e.preventDefault();
var f = e.target,
formData = new FormData(f),
xhr = new XMLHttpRequest();
xhr.open("POST", f.action);
xhr.send(formData);
}
对于jQuery,还有一个强大的插件jquery.form.js,利用这个插件,我们可以这么提交:
$('.send-message').click(function(e){
e.preventDefault();
if(self.validateForm(VALIDATE_TYPE.TEST_MESSAGE)){
$('#main-form').ajaxSubmit({
url: '/message/send_test_message.htm',
success: function(res){
if(typeof res === 'string')
res = JSON.parse(res);
console.log(res);
if(res.result === 'success'){
$('.test-success').removeClass('hide');
}
else{
alert(res.errorMsg);
$('.test-success').addClass('hide');
}
},
error: function(xhr, type){
$('.test-success').addClass('hide');
alert('提交测试失败,请重试!');
console.log('Ajax error! ' + type);
}
});
}else{
$('.test-success').addClass('hide');
}
});
利用ajaxSubmit,我们可以设置提交的url,以及成功和失败的回调函数,在处理业务时的确方便很多。而且不用手动序列化提交的表单数据。
ajaxSubmit还有一个强大的地方是能够处理文件的提交。
表单文件上传
下面是一个表单文件上传的例子:
<form action="/message/upload_image.htm" method="post" enctype="multipart/form-data" class="postimg-form">
<div class="form-group">
<input name="file" id="file" type="file" class="send-file" style="display: inline-block;"/>
</div>
<div class="urlinput-wrap">
<span>图片URL:</span>
<input name="picurlList" type="text" value="$!{picurlList}" class="img-url not-hidden"></input>
</div>
<button type="button">取消</button>
<input type="submit" class="commit-changepic">确定</button>
</form>
对于文件上传,必须采用post方式,并且form元素的enctype需要设置为multipart/form-data。
表单的enctype一般常用的有两种:
application/x-www-form-urlencoded:
这是默认的编码方式。它只处理表单域里的value属性值,采用这种变法方式的表单会将表单域的值处理成URL方式。
multipart/form-data:
这种编码方式会以二进制流的方式来处理表单数据,这中编码方式会把文件域指定的文件内容也封装到请求参数里。
用form的submit提交文件,会导致刷新页面,或者无法在提交成功后在回调函数中处理相应的业务。
而一般的ajax无法满足文件的上传(HTML5提出了XMLHttpRequest对象的第二版,从此ajax能够上传文件了。)。所幸的是,ajaxSubmit可以支持文件的提交。
示例代码如下:
$('.commit-changepic').click(function(e){
e.preventDefault();
$('.postimg-form').ajaxSubmit({
success: function(res){
console.log(res);
console.log(res.fileUrl);
if(res.fileUrl){
$('.poster-img').attr('src',res.fileUrl);
$($('.img-url')[0]).val(res.fileUrl);
}else{
alert('图片上传失败!');
}
},
error: function(res){
console.log(res);
alert('图片上传失败!');
}
});
});
用H5的FormData上传文件,示例如下:
if(window.FormData) {
var formData = new FormData();
// 建立一个upload表单项,值为上传的文件
formData.append('upload', document.getElementById('upload').files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', $(this).attr('action'));
xhr.onload = function () {
if (xhr.status === 200) {
console.log('上传成功');
} else {
console.log('出错了');
}
};
xhr.send(formData);
}
ajaxSubmit上传文件的原理还不清楚(猜测可能使用iframe实现的),有空可以研究一下。。。