请您先登录,才能继续操作
锁定老帖子 主题:表单域与json数据间的交互
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-10-09
找了几个javascript的框架,都没有找到我想要的:
/** **json对象数据设置到表单域中 */ function jsonObjectToForm(form, jsonObject){ for(i = 0, max = form.elements.length; i < max; i++) { e = form.elements[i]; eName = e.name; if(eName.indexOf('.') > 0){ dotIndex = eName.indexOf('.'); parentName = eName.substring(0, dotIndex); childName = eName.substring(dotIndex+1); //迭代判断eName,组装成json数据结构 eValue = iterValueFromJsonObject(jsonObject, parentName, childName); }else{ eValue = jsonObject[eName]; } if(eValue && eValue != "undefined" && eValue != "null"){ switch(e.type){ case 'checkbox': case 'radio': if(e.value == eValue){ e.checked = true; } break; case 'hidden': case 'password': case 'textarea': case 'text': e.value = eValue; break; case 'select-one': case 'select-multiple': for(j = 0; j < e.options.length; j++){ op = e.options[j]; //alert("eName : " + eName + "; op value : " + op.value + "; eValue : " + eValue); if(op.value == eValue){ op.selected = true; } } break; case 'button': case 'file': case 'image': case 'reset': case 'submit': default: } } } } /** * json数组读写有两种方式 * 1: a.bs[0].id * 2: a["bs"][0]["id"] * 把表单转换成json数据格式 */ function formToJsonObject(form){ var jsonObject = {}; for(i = 0, max = form.elements.length; i < max; i++) { e = form.elements[i]; em = new Array(); if(e.type == 'select-multiple'){ for(j = 0; j < e.options.length; j++){ op = e.options[j]; if(op.selected){ em[em.length] = op.value; } } } switch(e.type){ case 'checkbox': case 'radio': if (!e.checked) { break; } case 'hidden': case 'password': case 'select-one': case 'select-multiple': case 'textarea': case 'text': eName = e.name; if(e.type == 'select-multiple'){ eValue = em; }else{ eValue = e.value.replace(new RegExp('(["\\\\])', 'g'), '\\$1'); } //判断是否是对象类型数据 if(eName.indexOf('.') > 0){ dotIndex = eName.indexOf('.'); parentName = eName.substring(0, dotIndex); childName = eName.substring(dotIndex+1); //迭代判断eName,组装成json数据结构 iterJsonObject(jsonObject, parentName, childName, eValue); }else{ jsonObject[eName] = eValue; } break; case 'button': case 'file': case 'image': case 'reset': case 'submit': default: } } return jsonObject; } /** * 把表单元素迭代转换成json数据 */ function iterJsonObject(jsonObject, parentName, childName, eValue){ //pArrayIndex用于判断元素是否是数组标示 pArrayIndex = parentName.indexOf('['); //判断是否集合数据,不是则只是对象属性 if(pArrayIndex < 0){ var child = jsonObject[parentName]; if(!child){ jsonObject[parentName] = {}; } dotIndex = childName.indexOf('.'); if(dotIndex > 0){ iterJsonObject(jsonObject[parentName], childName.substring(0, dotIndex), childName.substring(dotIndex+1), eValue); }else{ jsonObject[parentName][childName] = eValue; } }else{ pArray = jsonObject[parentName.substring(0, pArrayIndex)]; //若不存在js数组,则初始化一个数组类型 if(!pArray){ jsonObject[parentName.substring(0, pArrayIndex)] = new Array(); } //取得集合下标,并判断对应下标是否存在js对象 arrayIndex = parentName.substring(pArrayIndex+1, parentName.length-1); var c = jsonObject[parentName.substring(0, pArrayIndex)][arrayIndex]; if(!c){ jsonObject[parentName.substring(0, pArrayIndex)][arrayIndex] = {}; } dotIndex = childName.indexOf('.'); if(dotIndex > 0){ iterJsonObject(jsonObject[parentName.substring(0, pArrayIndex)][arrayIndex], childName.substring(0, dotIndex), childName.substring(dotIndex+1), eValue); }else{ jsonObject[parentName.substring(0, pArrayIndex)][arrayIndex][childName] = eValue; } } } /** * 迭代json数据对象设置到表单域中 */ function iterValueFromJsonObject(jsonObject, parentName, childName){ //pArrayIndex用于判断元素是否是数组标示 pArrayIndex = parentName.indexOf('['); //判断是否集合数据,不是则只是对象属性 if(pArrayIndex < 0){ dotIndex = childName.indexOf('.'); if(dotIndex > 0){ return iterValueFromJsonObject(jsonObject[parentName], childName.substring(0, dotIndex), childName.substring(dotIndex+1)); }else{ return jsonObject[parentName][childName] } }else{ pArray = jsonObject[parentName.substring(0, pArrayIndex)]; //取得集合下标,并判断对应下标是否存在js对象 arrayIndex = parentName.substring(pArrayIndex+1, parentName.length-1); var c = jsonObject[parentName.substring(0, pArrayIndex)][arrayIndex]; dotIndex = childName.indexOf('.'); if(dotIndex > 0){ return iterValueFromJsonObject(jsonObject[parentName.substring(0, pArrayIndex)][arrayIndex], childName.substring(0, dotIndex), childName.substring(dotIndex+1)); }else{ return jsonObject[parentName.substring(0, pArrayIndex)][arrayIndex][childName] } } }
欢迎大家讨论,最近在研究jsp页面纯净,只与js有关,但这将导致rich client
so bad 不知道有什么好的建议没 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-10-09
不用 var 声明函数级变量是个坏习惯
|
|
返回顶楼 | |
发表时间:2008-10-09
fins 写道 不用 var 声明函数级变量是个坏习惯 对,要改正 |
|
返回顶楼 | |
发表时间:2008-10-09
挑一些 小毛病:
不用 var 声明函数级变量是个坏习惯 if(eValue && eValue != "undefined" && eValue != "null") 这句判断欠妥 json 中包含数组的情况考虑不周 form中有多个name相同元素的情况考虑不周 多选select情况考虑不周 checkbox radiobox 考虑不周 disabled 和 readonly 的情况 考虑不周 元素没有name时的策略是什么? 没有name就不处理 还是没有name取id?? 最后给个参数选择 总结: lz写的函数 目前还不适合在实际中使用 |
|
返回顶楼 | |
发表时间:2008-10-09
fins 写道 挑一些 小毛病: 不用 var 声明函数级变量是个坏习惯 if(eValue && eValue != "undefined" && eValue != "null") 这句判断欠妥 json 中包含数组的情况考虑不周 form中有多个name相同元素的情况考虑不周 多选select情况考虑不周 checkbox radiobox 考虑不周 disabled 和 readonly 的情况 考虑不周 元素没有name时的策略是什么? 没有name就不处理 还是没有name取id?? 最后给个参数选择 总结: lz写的函数 目前还不适合在实际中使用 因为在后台的话,是把json格式数据转换成对象,所以若多个name相同的话,那就要求是:name[0]、name[1]。。。这样来构造数组形式。 多选select情况考虑不周 ---指的是select-multiple吗? checkbox radiobox 考虑不周 ---请指出? disabled 和 readonly 的情况 考虑不周 ---请指出? 谢谢指点。。。 |
|
返回顶楼 | |
发表时间:2008-10-10
哈哈,终于看到有人和我有相同的想法了,(以前没有发现). 不过,其实这个想法可以延伸的,而且我已经延伸了.那就是: 既然是要得到JSON的数据,那一定和form有关么?非要从form中获取么? 当然不是.因此我写了一个基于jQuery的扩展 /* * jQuery Ajax By Name Plugin * * licensed under the MIT licenses: * http://www.opensource.org/licenses/mit-license.php * * Author achun (achun.shx at gmail.com) * Create Date: 2008-6-21 * Last Date: 2008-6-21 * Revision:2.8.6.21 */ (function($) { /** * 获取鼠标点击的元素坐标 */ $.fn.clickPos = function(e){ var pos ={x:0,y:0}; if (e.offsetX != undefined) { pos.x = e.offsetX; pos.y = e.offsetY; } else if (typeof $.fn.offset == 'function') { var offset = this.offset(); pos.x = e.pageX - offset.left; pos.y = e.pageY - offset.top; } else { pos.x = e.pageX - this[0].offsetLeft; pos.y = e.pageY - this[0].offsetTop; } return pos; } /** * ajaxName() 根据标签name属性来提交数据,替代form提交方式 * options:{//与ajax的options是一样的结构 * data:{}//要附加提交的数据 * } * successful:如果元素有有效值,defualt:true */ $.fn.ajaxName = function(options,successful) { if(options==undefined) options={}; options.data = options.data || {}; successful = successful == undefined ? true:successful; var data = {}; var name= options.name || ''; this.each(function() { var el=this,o=$(this),n = o.attr('name'),hasval = o.attr('value')!=undefined; if (!n) return; var t = el.type, tag = el.tagName.toLowerCase(); if (n=='/'){ if (name=='') name = hasval?o.attr('value'):o.text(); return; } if (successful && (el.disabled || t == 'reset' || t == 'button' || (t == 'checkbox' || t == 'radio') && !el.checked || (t == 'submit' || t == 'image') || tag == 'select' && el.selectedIndex == -1)) return; var v= hasval? o.attr('value') :o.hasClass('ValueByText')?o.text():o.html(); if (v == undefined) return; if (n.indexOf('.')>0){ n=n.split('.'); var len=n.length - 1; var b=data; $.each(n,function(i){ if (i!=len){ if(b[this] == undefined) b[this]={}; b=b[this]; }else b[this]=v; }); }else if (n.indexOf('[]')>0){ n=n.slice(0,n.length-2); if(data[n] == undefined) data[n]=[]; data[n].push(v); }else{ data[n]=v; } }); var dat={}; if (name){ dat[name]=data; data=dat[name]; }else dat=data; for (var o in options.data){ data[o]=options.data[o]; }; options.data=dat; return options.data; }; })(jQuery); 其中的clickPos扩展是为了取得图片点击提交点击坐标使用的扩展. 使用方法: 首先要调用这个使用,肯定需要element有name属性.调用类似这样的语法: var jsondat=$('#id [@name]').ajaxname() 其次:我对name='/'的element做了特殊处理,比如: <div name='/' value='foo'><span name='user'>youname</span></div> 得到的结果是: {foo:{user:"youname"}} 至于提交那是另外一件事情了.
另外就是: 1.我的这个获取数组下标是自动增加下标的,写法类似这个 <li name='a[]'>a0</li><li name='a[]'>a1</li><li name='a[]'>a2</li> 如果不符合你的习惯,可以按照你上面的代码修改一下了. 2.支持"."操作符 <li name='a.a'>a</li><li name='a.b'>b</li><li name='a.c'>c</li> 将获得 {a:{a:'a',b:'b',c:'c'}}
|
|
返回顶楼 | |
发表时间:2008-10-10
多选select情况考虑不周
---指的是select-multiple吗? 答: 是的 引用 因为在后台的话,是把json格式数据转换成对象,所以若多个name相同的话,那就要求是:name[0]、name[1]。。。这样来构造数组形式。
你可能没理解我的意思 要么就是我没理解你. 用示例来说明吧 有这样一个json { name : '张一' , sister : [ '张二', '张三','张四' ] } 有这样一个form <form> 姓名:<input type='text' name='name' /> 姐妹们: <input type='text' name='sister' /> <input type='text' name='sister' /> <input type='text' name='sister' /> </form> 问: 用你的函数 怎么把 这个json 添到这个form 里? 反过来又怎么从form里取数据出来 拼装成示例中那种格式的json? 引用 checkbox radiobox 考虑不周 ---请指出? disabled 和 readonly 的情况 考虑不周 ---请指出? 这几个你自己思考一下吧(1 考虑不周 2 有bug) 建议你找一些现有的例子 看看人家是怎么处理的. |
|
返回顶楼 | |
发表时间:2008-10-10
谢谢您的提醒
|
|
返回顶楼 | |
发表时间:2008-10-10
不知道您有没有在后台转换json数据格式为java对象呢?
对于select-multiple的数据类型(int、String) 封装成json时,有什么好的办法只把int的整成[1, 2, 3],String的整成['1', '2', '3'] 因为在java中,可能有一类型int[],但传['1', '2', '3']时,真正转换会报错的。 不知道我这样说明白没? 谢谢 |
|
返回顶楼 | |
发表时间:2008-10-10
你用什么工具做的转换啊?
json和java转换的东西我做过很多 你这个问题 建议在转换前就处理好 是int 型 还是string 型你必须要明确的告诉 转换器 目前我的做法是 json --->java 时 , 按字符串从sjon中取值 在向 java对象中赋值时 判断对象的类型 然后做响应的转换. btw: select-multiple的数据在客户端时 都是字符串型 最后到后台是什么类型取决于你的需求. |
|
返回顶楼 | |