最近根據自身項目的特色寫了一個表單序列化與反序列化工具,該工具是基於jQuery的,生成JSON對象。雖然jQuery自己已經實現了類似功能和API($().serialize() 和 $().serializeArray()),但使用起來不是特別方便。如下是個人實現方式:javascript
序列化表單值,結果以key/value形式返回JSON數據。key爲表單對象名稱(name||id),value爲其值。css
表單容器:一般是一個form表單(若是不存在就以body爲父容器)或div,裏面包含輸入標籤和子容器;html
子容器(也能夠沒有):必須包括屬性fieldset="XXX" div標籤,裏面包含輸入標籤和子容器。序列化後將生成以XXX爲主鍵的json對象.若是子容器存在嵌套則以fieldset爲主鍵生成不一樣分組的json對象。java
輸入標籤:輸入標籤爲input類型標籤(包括:'checkbox','color','date','datetime','datetime-local','email','file','hidden','month','number','password','radio','range','reset','search','submit','tel','text','time ','url','week')。而'button','reset','submit','image'會被過慮掉。jquery
示例HTML頁面(下載): git
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Form Serialize & Deserialize</title> <script src="js/jquery-1.7.2.min.js"></script> <script src="js/iTsai-webtools.form.js"></script> </head> <style type="text/css"> .cls { border:2px solid #f00; } </style> <body> <input type="button" value="Serialize.." onclick="console.log(iTsai.form.serialize($('#frm')));"/> <input type="button" value="Deserialize.." onclick="console.log(iTsai.form.deserialize($('#frm'),json));"/> <hr/> <form id="frm" name="frm" style="border:1px solid #ccc;padding:20px;"> <input type="button" id="btn1" name="btn" value="btn001"> <input type="reset" id="reset" name="reset" value="reset"> <input type="submit" id="submit" name="submit" value="submit"> <br> <br> <input type="number" id="number2" name="number" value="10086"> number <br> <input type="checkbox" id="chk_00" name="chk0" value="chk-0"/> <input type="checkbox" id="chk_01" name="chk1" value="chk-1" checked/> chekckbox <br> <input type="radio" id="radio-0" name="radiox" value="0"> <input type="radio" id="radio-1" name="radiox" value="1" checked> <input type="radio" id="radio-2" name="radiox" value="2"> radio <br> <select name="sel"> <option value="1">1</option> <option value="2" selected>2</option> </select> select <br/> <select id="sel-multi" name="multi" multiple="multiple"> <option value="111">111</option> <option value="222" selected="selected">222</option> <option value="333" selected="selected">333</option> <option value="444">444</option> </select> select-multiple<br/> <div fieldset="basic" class="cls"> <input type="password" id="pwd" name="pwd" value="123465"> password <br> <input type="text" id="txt" name="txt" value="this is my info"> text <br> </div> <input type="color" id="clr-01" name="color" value="#fff"/> color <br> <input type="date" id="date" name="date" value="2012-12-23"/> date <br> <input type="datetime" id="dt" name="dt" value="2012-12-23 12:12:12"/> datetime <br> <input type="datetime-local" id="dtl" name="dtl" value="2012-12-23 12:12:12"/> datetime-local <br> <input type="time" id="time" name="time" value="12:23:11"> time <br> <input type="week" id="week" name="week" value="Mon."> week <br> <input type="month" id="month" name="month" value="12"> month <br> <input type="email" id="email" name="email" value="demo@xy.com"/> email <br> <input type="file" id="file" name="fileurl" value="D:\\txt.txt"/> file <br> <input type="hidden" id="hide" name="hide" value="_VALUE"/> hidden <br> <input type="image" id="image" name="image" src="../image/bt_blue.png" value="imag-value"> image <br> <div fieldset="user" class="cls"> <input type="number" id="number" name="number" value="10016"> number <br> <input type="range" id="range" name="range" min="10" max="110" value="12"/> range <br> <input type="search" id="sch" name="sch" value="search text.." > search <br> <input type="tel" id="tel" name="tel" value="023-11112222"> tel <br> <input type="url" id="url" name="url" value="https://www.google.com"> url <br> <textarea id="content" name="cont" rows="3" cols="10">textarea info.</textarea> </div> </form> <script type="text/javascript"> //測試反序列化示例,序列化後將生成一樣數據格式的JSON對象 var json = { "image" : "IMAGE -VALUE", "hide" : "_VALUE111", "fileurl" : "C:txt", 'number' : 1008655, "email" : "123@xy.com", "month" : "11", "week" : "Sat.", "time" : "11:23:11", "dtl" : "2011-12-23 12:12:12", "dt" : "2011-12-23 12:12:12", "date" : "2011-12-23", "color" : "#ddd", "radiox" : "2", "chk1" : true, "chk0" : false, "basic" : { pwd : 'qwert', txt : 'yiui' }, "user" : { number : 111, range : 12131, sch : 'sdfsaf', tel : '145', url : 'http://', content : 'content content content...' }, sel : '2', multi : [111,444] }; </script> </body> </html>
表單處理工具Javascript代碼(下載): github
/** * iTsai WebTools(Web開發工具集) * * @author Chihpeng Tsai(470597142@qq.com) * @description 表單處理工具. */ (function() { if (!window.iTsai) iTsai = {}; })(); iTsai.form = { toString : function() { return 'iTsai.form - 表單處理工具'; }, /** * 獲取單選框值,若是有表單就在表單內查詢,不然在全文查詢 * * @param{String}name radio名稱 * @param{$()} frm jQuery object * @returns */ getRadioValue : function(name, frm) { if (frm && frm.find) return frm.find('input[name="' + name + '"]:checked').val(); return $('input[name="' + name + '"]:checked').val(); }, /** * 設置單選框值,若是有表單就在表單內查詢,不然在全文查詢 * * @param{String}name radio名稱 * @param{String} value * @param{$()} frm * @returns */ setRadioValue : function(name, value, frm) { if (frm && frm.find) return frm .find('input[name="' + name + '"][value="' + value + '"]') .attr('checked', true); return $('input[name="' + name + '"][value="' + value + '"]').attr( 'checked', true); }, /** * 設置select下拉框的值 * * @param{String} selectId 下拉框id號 * @param{String/Number} value 值 * @param{$()} form jQuery object * @returns */ setSelectValue : function(selectId, value, frm) { if (frm && frm.find) return frm.find('#' + selectId + ' option[value="' + value + '"]') .attr('selected', true); return $('#' + selectId + ' option[value="' + value + '"]').attr( 'selected', true); }, /** * 在id區域內執行回車提交數據<br> * 實際處理中應該將提交按鍵放在id區域外,避免重複提交 * * @param{String} id 被綁定對象的ID號 * @param{Function} fn 要選擇的函數 * @returns {Boolean} */ bindingEnterKey : function(id, fn) { $('#' + id).keydown(function(e) { if (e.keyCode == 13) { if (fn) fn(); } }); }, /** * 將輸入控件集合序列化成對象<br> * 名稱或編號做爲鍵,value屬性做爲值 * * @param {Array} * inputs input/select/textarea的對象集合 * @return {object} json 對象 {key:value,...} */ _serializeInputs : function(inputs) { var json = {}; if (!inputs) { return json; } for ( var i = inputs.length - 1; i >= 0; i--) { var input = $(inputs[i]); var type = input.attr('type'); if (type) { type = type.toLowerCase(); } var tagName = input.get(0).tagName; var id = input.attr('id'); var name = input.attr('name'); var value = null; // 判斷輸入框是否已經序列化過 if (input.hasClass('_isSerialized')) { continue; } // input輸入標籤 if (tagName == 'INPUT' && type) { switch (type) { case 'checkbox': { value = input.is(':checked'); } break; case 'radio': { if (input.is(':checked')) { value = input.attr('value'); } else { continue; } } break; default: { value = input.val(); } } } else { // 非input輸入標籤,如:select,textarea value = input.val(); } json[name || id] = value; // 清除序列化標記 input.removeClass('_isSerialized'); } return json; }, /** * 將值填充到輸入標籤裏面 * * @param{Array} inputs 輸入標籤集合 * @param{String/Number} value 值 * @returns {___anonymous188_8285} */ _deserializeInputs : function(inputs, value) { if (!inputs && value == null) { return this; } for ( var i = inputs.length - 1; i >= 0; i--) { var input = $(inputs[i]); // 判斷輸入框是否已經序列化過 if (input.hasClass('_isSerialized')) { continue; } var type = input.attr('type'); if (type) { type = type.toLowerCase(); } if (type) { switch (type) { case 'checkbox': { input.attr('checked', value); } break; case 'radio': { input.each(function(i) { var thiz = $(this); if (thiz.attr('value') == value) { thiz.attr('checked', true); } }); } break; default: { input.val(value); } } } else { input.val(value); } input.addClass('_isSerialized'); } return this; }, /** * 在分組中查找 fieldset (如:fieldset="user")開頭的數據域<br> * * @param {Array} * groups 輸入框分組容器集合 * @return {Object} json 對象 {key:value,...} */ _serializeGroups : function(groups) { var json = {}; if (!groups) { return json; } for ( var i = groups.length - 1; i >= 0; i--) { var group = $(groups[i]); var key = group.attr('fieldset'); if (!key) { continue; } var inputs = group .find('input[type!=button][type!=reset][type!=submit],select,textarea'); json[key] = this._serializeInputs(inputs); // 添加序列化標記 inputs.addClass('_isSerialized'); } return json; }, /** * 序列化表單值,結果以key/value形式返回key爲表單對象名稱(name||id),value爲其值.<br> * HTML格式:<br> * 1).表單容器:一般是一個form表單(若是不存在就以body爲父容器),裏面包含輸入標籤和子容器;<br> * 2).子容器(也能夠沒有):必須包括屬性fieldset="XXX" div標籤,裏面包含輸入標籤和子容器。<br> * 序列化後將生成以XXX爲主鍵的json對象.若是子容器存在嵌套則以fieldset爲主鍵生成不一樣分組的json對象.<br> * 3).輸入標籤:輸入標籤爲input類型標籤(包括:'checkbox','color','date','datetime','datetime-local',<br> * 'email','file','hidden','month','number','password','radio','range * ','reset','search','submit',<br> * 'tel','text','time ','url','week'). * 而'button','reset','submit','image'會被過慮掉. * * @param{$()} frm jQuery表單對象 * @returns {Object} json對象 最多包含兩層結構 */ serialize : function(frm) { var json = {}; frm = frm || $('body'); if (!frm) { return json; } var groups = frm.find('div[fieldset]'); var jsonGroup = this._serializeGroups(groups); var inputs = frm .find('input[type!=button][type!=reset][type!=submit][type!=image],select,textarea'); var json = this._serializeInputs(inputs); for ( var key in jsonGroup) { json[key] = jsonGroup[key]; } return json; }, /** * 填充表單內容:將json數據形式數據填充到表單內,只解析單層json結構 * * @param{$()} frm jQuery表單對象(或其它容器標籤對象,如:div) * @param{Object} json 序列化好的json數據對象,最多隻包含兩層嵌套 * @returns {Object} iTsai.form 對象 */ deserializeSimple : function(frm, json) { frm = frm || $('body'); if (!frm || !json) { return this; } var _deserializeInputs = this._deserializeInputs; for ( var key in json) { var value = json[key]; _deserializeInputs(frm, key, value); } return this; }, /** * 獲取合法的輸入標籤 * * @param {$()} * container 標籤容器 * @returns {[]} inputs jQuery對象數組 */ _filterInputs : function(container) { var inputs = $(container .find('input[type!=button][type!=reset][type!=submit][type!=image][type!=file],select,textarea')); return inputs; }, /** * 查找符合條件的輸入標籤 * * @param{Array} inputs jQueery輸入標籤數組 * @param{String} key 查詢關鍵字 * @returns{Array} input 標籤數組 */ _findInputs : function(inputs, key) { var input = $(inputs.filter('input[name=' + key + '],input[id=' + key + '],textarea[name=' + key + '],textarea[id=' + key + '],select[name=' + key + '],select[id=' + key + ']')); return input; }, /** * 填充表單內容:將json數據形式數據填充到表單內,最多解析兩層json結構 * * @param{$()} frm jQuery表單對象(或其它容器標籤對象,如:div) * @param{Object} json 序列化好的json數據對象,最多隻包含兩層嵌套 * @returns {Object} iTsai.form 對象 */ deserialize : function(frm, json) { frm = frm || $('body'); if (!frm || !json) { return this; } // 緩存json第一層數據對象 var objects = {}; // 緩存json嵌套層數據(第二層),將首先被賦值,以免覆蓋 var groups = {}; // 數據分組 for ( var key in json) { var value = json[key]; if (typeof value == 'object' && !$.isArray(value)) { groups[key] = value; } else { objects[key] = value; } } var _deserializeInputs = this._deserializeInputs; var _filterInputs = this._filterInputs; var _findInputs = this._findInputs; // 填充嵌套層數據 for ( var key in groups) { var json = groups[key]; var div = frm.find('div[fieldset="' + key + '"]'); if (!div.length) { continue; } var inputs = _filterInputs(div); if (!inputs.length) { continue; } for ( var k in json) { var val = json[k]; var input = _findInputs(inputs, k); _deserializeInputs(input, val); } } // 填充第一層數據 var inputs = _filterInputs(frm); for ( var key in objects) { var value = objects[key]; var input = _findInputs(inputs, key); _deserializeInputs(input, value); } inputs.filter('._isSerialized').removeClass('_isSerialized'); return this; } };
//將iTsai.form.serialize綁定到jQuery對象上,能夠直接在jQuery對象上調用。如:$('#fr').frmSerizlize(); //此部分代碼也能夠刪除。 (function ($) { $.fn.frmSerialize = function() { return iTsai.form.serialize($(this)); }; $.fn.frmDeSerialize = function(json) { return iTsai.form.deserialize($(this), json); }; }(jQuery));
$('#_lan').frmSerialize();web
工具使用: json
序列化表單:iTsai.form.serialize($('#frm')),生成json對象,若是部分表單對象用<div fieldset="user"> ... </div>,包裹起來,將生成key爲user的子對象;數組
反序列化表單:iTsai.form.deserialize($('#frm'),json),原理與上面相反。
此工具最大的特色就是能夠用 <div fieldset="user"> ... </div> 將表單分紅不一樣的組,使生成的JSON對象層次更清晰。
使用截圖:
擴展工具:https://github.com/iiTsai/iTsai-Webtools 是一些我的日常用的JS小工具,有興趣的朋友能夠了解下……