2010-08-05 87 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

相關問題