一、应用场景
form提交时,使用ajax提交。
二、效果
通过本工具,实现表单所有form的快速序列化和json化,使前端人员在ajax提交form表单的时,脱离重复性的,大劳动量的手动抽取form属性和对应的值。
注:本工具的功能,也可以通过原生的FormData([HTMLFormElement]) + JSON.stringify() + JSON.parse()实现。
三、源码[form.js]
//将数据序列化成 url请求方式的编码
function serialize(form){
var len=form.elements.length;//表单字段长度;表单字段包括<input><select><button>等
var field=null;//用来存储每一条表单字段
var parts=[];//保存字符串将要创建的各个部分
var opLen,//select中option的个数
normalValue,//text,number,date,textarea的值
opValue;//select中option的值
//遍历每一个表单字段
for(var i=0;i<len;i++){
field=form.elements[i];
/*检测每一个表单字段的类型,做出不同的处理:
*1.最麻烦的就是select:它可能是单选框也可能是多选框,这里的代码适合于这两种框。在找到一个选中的项之后,需要确
*定使用什么值。如果不存在value特性或者虽然存在但是值为空字符串,都要使用选项的文本来代替。为查这个属性,在DOM兼
*容的浏览器中使用hasAttribute()方法,在IE中需要使用特性的specified属性。
*2.表单中如果包括<fieldset>
*元素,则该元素会出现在表单集合中但是没有type属性。因此,如果type属性未定义,则不必对其进行序列化;同样,对于
*各种按钮以及文件输入字段都是如此。
*3.对于单选按钮和复选框,要检查其checked属性是否被设置为false,如果是则退出switch语句,如果checked属性为true
*则继续进行default内容,即将当前的名称和值进行编码,然后添加到parts数组中。函数的最后一步就是使用join格式化整
*个字符串,也就是用和好来分隔每一个表单字段
*/
switch(field.type){
case"select-one":
case"select-multiple":
if(field.name.length){
for(var j=0,opLen=filed.options.length;j<opLen;j++){
option=field.options[j];
if(option.selected){
opValue='';
if(option.hasAttribute){
opValue=(option.hasAttribute('value')?option.value:option.text);
}else{
opValue=(option.hasAttribute['value'].specified?option.value:option.text);//IE下
}
parts.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(opValue));
} }
}
break;
case undefined:
case "file":
case "submit":
case "reset":
case "button":
break;
case "text":
case "number":
case "date":
case "textarea":
if(field.name.length){
normalValue = field.value;
parts.push(encodeURIComponent(field.name)+'='+encodeURIComponent(normalValue));
}
break;
case "radio":
case "checkbox":
if(!field.checked){
break;
}
default:
if(field.name.length){
parts.push(encodeURIComponent(field.name)+'='+encodeURIComponent(opValue));
}
break;
}
}
return parts.join("&");
}
//将form数据字符串化成符合json格式的字符串
function stringify(form){
var len=form.elements.length;//表单字段长度;表单字段包括<input><select><button>等
var field=null;//用来存储每一条表单字段
var parts=[];//保存字符串将要创建的各个部分
var opLen,//select中option的个数
normalValue,//text,number,date,textarea的值
opValue;//select中option的值
//遍历每一个表单字段
for(var i=0;i<len;i++){
field=form.elements[i];
/*检测每一个表单字段的类型,做出不同的处理:
*1.最麻烦的就是select:它可能是单选框也可能是多选框,这里的代码适合于这两种框。在找到一个选中的项之后,需要确
*定使用什么值。如果不存在value特性或者虽然存在但是值为空字符串,都要使用选项的文本来代替。为查这个属性,在DOM兼
*容的浏览器中使用hasAttribute()方法,在IE中需要使用特性的specified属性。
*2.表单中如果包括<fieldset>
*元素,则该元素会出现在表单集合中但是没有type属性。因此,如果type属性未定义,则不必对其进行序列化;同样,对于
*各种按钮以及文件输入字段都是如此。
*3.对于单选按钮和复选框,要检查其checked属性是否被设置为false,如果是则退出switch语句,如果checked属性为true
*则继续进行default内容,即将当前的名称和值进行编码,然后添加到parts数组中。函数的最后一步就是使用join格式化整
*个字符串,也就是用和好来分隔每一个表单字段
*/
switch(field.type){
case"select-one":
case"select-multiple":
if(field.name.length){
for(var j=0,opLen=filed.options.length;j<opLen;j++){
option=field.options[j];
if(option.selected){
opValue='';
if(option.hasAttribute){
opValue=(option.hasAttribute('value')?option.value:option.text);
}else{
opValue=(option.hasAttribute['value'].specified?option.value:option.text);//IE下
}
parts.push(encodeURIComponent('"'+ field.name + '":"') + encodeURIComponent(opValue)) + '"';
} }
}
break;
case undefined:
case "file":
case "submit":
case "reset":
case "button":
break;
case "text":
case "number":
case "date":
case "textarea":
if(field.name.length){
normalValue = field.value;
parts.push('"' + field.name + '":"' + normalValue.trim() + '"');
}
break;
case "radio":
case "checkbox":
if(!field.checked){
break;
}
default:
if(field.name.length){
parts.push('"' + field.name + '":"' + normalValue+ '"');
}
break;
}
}
return '{' + parts.join(',') + '}';
}
四、注意
json字符串实例化为json对象时,对json字符串的格式有严格规定,属性名和属性值必须用双引号引起,否则在调用JSON转化时,将报错,且实例化失败。
五、无关
格式化Js原生日期为字符串 形如:2008/12/12 12:12:30
function formatDateToStr(date){
var str = "";
str += date.toLocaleDateString() + " "; str += date.getHours() + ":";
str += date.getMinutes() + ":";
str += date.getSeconds();
return str;
}
function formatDateToStr(date){
var str = "";
str += date.toLocaleDateString() + " ";
str += date.getHours() + ":";
str += date.getMinutes() + ":";
str += date.getSeconds();
return str;
}