2010-08-05 44 views
1

是否有方法将表单转换为基于某种结构化表单的复杂JavaScript对象?如何将html表单转换为复杂的JavaScript对象

现在,我不知道这是否应该以更好的方式来完成,但基本上我想是这样的:

<form> 
    <input name="Foo" value="1" /> 
    <input name="Parent.Child1" value="1" /> 
    <input name="Parent.Child2" value="2" /> 
</form> 

,我想这在JavaScript:

var form = GetForm(); 
var obj = ConvertFormToComplexObject(form); 

// 
// Followings should be true 
// 
// obj.Foo == 1; 
// obj.Parent != null 
// obj.Parent.Child1 == 1; 
// obj.Parent.Child2 == 2; 
// 

任何建议?

感谢,

+1

为了什么目的呢?这看起来像是基本DOM脚本的变体;为什么不学会使用正常的DOM脚本? – 2010-08-05 19:56:53

+0

嗯..基本上,我有一个动态表单元素的表单。用户可以添加一个“对象”列表,其中每个“对象”都包含一个整数和一个字符串。 我可以通过命名约定如name =“1_Integer”或name =“2_String”来保持表单不变,但我必须编写一个解析器。 如果我正确地构建JavaScript对象。我可以使用Json将其序列化并让Json处理复杂性。 – 2010-08-05 20:41:33

回答

2

我写了一个插件来做到这一点。 希望它能帮助那里的人。 让我知道如果你发现任何错误。

这里是serializeObject的代码。JS:

$.fn.serializeObject = function() { 
    var o = {}; 
    var a = this.serializeArray(); 
    $.each(a, function() { 

     var arrayIndex = function(name) { 
      //note: 2d array not handled 

      var startIndex = name.indexOf('['); 
      var endIndex = name.indexOf(']'); 

      if (startIndex == -1 || endIndex == -1 || endIndex != name.length - 1) 
       return null; 

      return name.substr(startIndex + 1, endIndex - startIndex - 1); 
     } 

     var trimArrayIndex = function(name) { 
      var startIndex = name.indexOf('['); 
      return name.substr(0, startIndex); 
     } 

     var createObject = function(obj, className, value) { 
      if (className.length == 0) 
       return; 

      var classNames = className.split("."); 

      if (classNames.length == 1) { 

       if (obj[classNames[0]] == null) { 
        obj[classNames[0]] = value; 
       } 
       else if (obj[classNames[0]] instanceof Array) { 
        obj[classNames[0]].push(value); 
       } 
       else { 
        var temp = obj[classNames[0]]; 

        obj[classNames[0]] = new Array(); 
        obj[classNames[0]].push(temp); 
        obj[classNames[0]].push(value); 
       } 

       return; 
      } 

      var index = arrayIndex(classNames[0]); 
      var isArray = index != null; 

      if (!isArray) { 
       if (obj[classNames[0]] == null) { 
        obj[classNames[0]] = new Object(); 
       } 

       createObject(obj[classNames[0]], className.substr(classNames[0].length + 1), value); 
      } 
      else { 
       var aryName = trimArrayIndex(classNames[0]); 

       if (obj[aryName] == null) { 
        obj[aryName] = new Array(); 
       } 
       else if (!obj[aryName] instanceof Array) { 
        throw "unable to serialize " + aryName + " as an array"; 
       } 

       var ary = obj[aryName]; 
       var nextObj; 

       if (ary[parseInt(index)] == null) { 
        ary[parseInt(index)] = new Object(); 
       } 

       nextObj = ary[parseInt(index)]; 

       createObject(nextObj, className.substr(classNames[0].length + 1), value); 
      } 
     } 

     createObject(o, this.name, this.value || ''); 
    }); 
    return o; 
}; 

$.fn.replaceStarWithIndex = function() { 
    var a = this.serializeArray(); 
    var form = this; 


    var arrayIndex = function(name) { 
     var startIndex = name.indexOf('['); 
     var endIndex = name.indexOf(']'); 

     if (startIndex == -1 || endIndex == -1) { 
      return null; 
     } 

     return name.substr(startIndex + 1, endIndex - startIndex - 1); 
    } 

    var trimArrayIndex = function(name) { 
     var startIndex = name.indexOf('['); 
     return name.substr(0, startIndex); 
    } 

    for (var key in a) { 
     var index = arrayIndex(a[key].name); 

     if (index == null || index != "*") { 
      continue; 
     } 

     var count = 0; 
     var trimName = trimArrayIndex(a[key].name); 

     while (true) { 
      var elementName = a[key].name.replace('*', count); 
      var element = form[0][elementName]; 

      if (element == null) { 
       $(form[0][a[key].name]).first().attr('name', elementName); 
       break; 
      } 
      count++; 
     } 
    } 
} 

这里的测试:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head> 
    <title>Test</title> 
    <link rel="stylesheet" href="http://github.com/jquery/qunit/raw/master/qunit/qunit.css" type="text/css" media="screen" /> 

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" ></script> 
    <script type="text/javascript" src="http://github.com/jquery/qunit/raw/master/qunit/qunit.js" ></script> 
    <script type="text/javascript" src="serializeObject.js" ></script> 
</head> 

<body> 

<h1 id="qunit-header">Test serializeObject</h1> 
<h2 id="qunit-banner"></h2> 
<h2 id="qunit-userAgent"></h2> 
<ol id="qunit-tests"></ol> 

<!--Test Form --> 

<form id="form1" style="display:none;"> 
    <input type="text" name="Parent.Child1" value="child1"/> 

    <input type="text" name="Parent.Child2" value="child2a"/> 
    <input type="text" name="Parent.Child2" value="child2b"/> 

    <input type="text" name="Parent.Child3" value="3"/> 
    <input type="text" name="Parent.Child3" value="2"/> 
    <input type="text" name="Parent.Child3" value="1"/> 

    <input type="text" name="Parent.Child4[0].Child1" value="11" /> 
    <input type="text" name="Parent.Child4[0].Child2" value="aa" /> 

    <input type="text" name="Parent.Child4[1].Child1" value="22" /> 
    <input type="text" name="Parent.Child4[1].Child2" value="bb" /> 



</form> 

<form id="form2" style="display:none;"> 
    <input type="text" name="Child1[0].Child1" value="0" /> 
    <input type="text" name="Child1[*].Child1" value="1" /> 
    <input type="text" name="Child1[*].Child1" value="2" /> 

    <input type="text" name="Child2[2]" value="2" /> 
    <input type="text" name="Child2[*]" value="0" /> 
    <input type="text" name="Child2[*]" value="1" /> 
</form> 

<script type="text/javascript"> 
    $(document).ready(function() { 
     var obj = $('#form1').serializeObject(); 

     test("Parent should exist", function() { 
      equals(true, obj.Parent != null); 
     }); 

     test("Child1 should exist within parent", function() { 
      equals(true, obj.Parent.Child1 != null); 
     }); 

     test("Should create array for items with same name", function() { 
      equals("child2a", obj.Parent.Child2[0]); 
      equals("child2b", obj.Parent.Child2[1]); 
      equals("3", obj.Parent.Child3[0]); 
      equals("2", obj.Parent.Child3[1]); 
      equals("1", obj.Parent.Child3[2]); 
     }); 


     test("Should allow array of objects", function() { 
      equals("11", obj.Parent.Child4[0].Child1); 
      equals("aa", obj.Parent.Child4[0].Child2); 
      equals("22", obj.Parent.Child4[1].Child1); 
      equals("bb", obj.Parent.Child4[1].Child2); 
     }); 

     $('#form2').replaceStarWithIndex(); 

     test("Should replace * with index", function() { 
      equals("0", $('#form2 input[name="Child1[0].Child1"]').val()); 
      equals("1", $('#form2 input[name="Child1[1].Child1"]').val()); 
      equals("2", $('#form2 input[name="Child1[2].Child1"]').val()); 

      equals("0", $('#form2 input[name="Child2[0]"]').val()); 
      equals("1", $('#form2 input[name="Child2[1]"]').val()); 
      equals("2", $('#form2 input[name="Child2[2]"]').val()); 
     }); 

    }); 
</script> 

</body> 
</html> 
0

我猜你所要求的document.forms [0]

类似:

变种形式= document.forms [0]; //或可document.getElementByName ...

那么你就可以访问它的值,你正在尝试:form.Foo = 1

你并不需要将其转换为复杂的对象DOM本身就是sufficent这

0
var form = document.forms[0]; 

回报HTML元素对象,你可以使用

form.Foo 

得到一个HTML元素太

但如果你想要得到的值,必须使用:

form.Foo.value 

form['Parent.Child1'].value; 

你可以看到这个DEMO

附:我认为ConvertFormToComplexObject()方法不好,你不需要创建它。

+0

感谢Zenofo,但我希望“Parent”是一个对象,所以如果我愿意,我可以选择将它序列化为Json。在你的情况下,form.Parent为null或form.Parent.Child1给出错误 – 2010-08-05 20:45:19

0

其名称[0]非常基本的版本,但它应该给你一个基本的了解如何工作。

$(function(){ 
    var elements = document.forms[0].elements, 
     foo = {}; 
    for(var i=0; i<elements.length; i++) { 
     var element = elements[i]; 
     var names = element.name.split('.'); 
     if(names.length >1) { 
      foo[names[0]] = foo[names[0]] || {}; 
      foo[names[0]][names[1]] = element.value; 
     } else { 
     foo[names[0]] = element.value; 
     } 

    } 
    console.log(foo) 
});​ 
0

众多Javascript库都具有此功能。我建议你使用他们的实现,或者至少看看他们是如何做到的。

原型:http://www.prototypejs.org/api/form/serialize

用法:$('id-of-form').serialize(true)

+0

我已经看过jQuery的一个,但它没有做“结构化”的对象序列化。实际上,它甚至不会将其序列化为对象。 离我最近的这个: http://stackoverflow.com/questions/1184624/serialize-form-to-json-with-jquery – 2010-08-06 20:05:33

相关问题