2013-07-10 37 views
1

我正在创建一个表单数据序列化函数,它通过AJAX将信息传递给PHP文件进行错误检查和解析。我知道我可以在技术上使用JQuery中的.serialize()方法,但我需要更多的控制数据。基本上我想将表单中的字段解析为多维JavaScript对象,然后将其转换为JSON以通过AJAX发送。我已经建立了一个大部分可行的方法,但仍然存在一些缺陷。这里是我的Javascript/JQuery代码:将HTML名称属性转换为Javascript对象

var formData = { }; 

function serializeAllFormData() { 
    $(':input').not('button').each(function() { 
     //This pulls the fields name for use in error message generation 
     var fieldName = $(this).parent().children('label').html(); 

     //Takes the value of the field 
     var value = $(this).val(); 

     //This section finds all fields that needs additional error checking like email/url 
     var allClasses = $(this).attr('class'); 
     allClasses = allClasses.match(/special_(\w*)/); 
     if (allClasses != null) { 
     var special = allClasses[1]; 
     } 
     else { 
      var special = ''; 
     } 

    //Takes the name attribute such as '[contact][email]' and makes an array of just the names. ['contact', 'email'] 
    var locationArray = $(this).attr('name').match(/\w+/g); 

    //Making a temporary object that will be nested. This object holds all the necessary information for parsing in my errorCheck.php file. 
    tempObj = { }; 
    tempObj[0] = value; 
    tempObj[1] = fieldName; 
    tempObj[2] = $(this).attr('name'); 
    tempObj[3] = special; 

    //Iterate through, starting with the smallest child of the name attribute and working backwards, nesting the objects 
    var length = locationArray.length; 
    for (i = length; i > 0; i--) { 
     locationName = locationArray[i-1]; 
     if (i > 1) { 
      var tempObj2 = { }; 
      tempObj2[locationName] = tempObj; 
      tempObj = tempObj2; 
     } 

     //For the last iteration, nest the object in the formData variable itself 
     if (i == 1) { 
      formData[locationName] = tempObj; 
     } 
    } 
}); 
    formData = JSON.stringify(formData); 
    return formData; 
} 

因此,如果它只是在一个维度上运行,它会很好用。即名称属性很简单,如name="[email]"name="[phone_number]"。但是,一旦它变成更复杂的多维字段,formData对象只保留最后一个字段。 formData对象在每次迭代期间被覆盖。一个例子是,如果我有这样的HTML结构:

<div><label>Email</label><input type="text" name="[contact][email]" /></div> 
<div><label>Phone Number</label><input type="text" name="[contact][phone]" /></div> 

如果我运行的方法,一般的结构是这样的:Object (contact => Object (phone => Object (0 => "", 1 => "Phone Number", 2 => "[contact][phone]", 3 => "")))

所以我需要一种方法来确保内现有的对象formData在每次迭代时都不会被覆盖。

感谢您的帮助!

+0

如果我正确地理解了你(基于你的问题的标题)你试图代表名称属性作为一个对象?如果,那么为什么不使用'element.getAttributeNode(“name”);'?如果你想要一些自定义类型属性使用'data-myattr =“”'http://ejohn.org/blog/html-5-data-attributes/ – Givi

+0

我会使用这种方法,但所有'element.getAttributeNode(' name');'returns是一个字符串。我需要一个可以转换为JSON的对象,以便在PHP文件解码时可以导航。 – MrGrinst

回答

0

尝试正确初始化您的临时变量。例如:

var tempObj = []; 

因为它现在正在创建全局变量,每次迭代都会重复使用它们。

+0

刚试过,没有帮助。我想我错误的顺序是问题所在。我试图从现在开始,重复到底部而不是从底部到顶部。 – MrGrinst

0

经过大量研究,我确定不可能使用JavaScript来完成我想要的功能,所以我创建了一个解决方法。我编辑了上面的代码,以便每个字段的索引键只是整个名称属性本身。因此,例如,如果name属性是[contact][email],那么生成的对象将如下所示:Object => ('[contact][email]' => Object (0 => '', 1 => 'Email', 2 => '[contact][email]', 3 => ''))。然后,一旦该异议转换为JSON,我将它通过AJAX传递给我的PHP文件。一旦在PHP文件,我运行下面的代码把它转换成一个多维数组:

PHP

$multiDimensional = array(); 

foreach ($formData as $key => $field) { 
    preg_match_all('/\w+/', $key, $keyArray); 
    $keyArray = $keyArray[0]; 
    $length = count($keyArray); 
    switch ($length) { 
     case 1: 
      $multiDimensional{$keyArray[0]} = $field; 
      break; 
     case 2: 
      $multiDimensional{$keyArray[0]}{$keyArray[1]} = $field; 
      break; 
     case 3: 
      $multiDimensional{$keyArray[0]}{$keyArray[1]}{$keyArray[2]} = $field; 
      break; 
     case 4: 
      $multiDimensional{$keyArray[0]}{$keyArray[1]}{$keyArray[2]}{$keyArray[3]} = $field; 
      break; 
     case 5: 
      $multiDimensional{$keyArray[0]}{$keyArray[1]}{$keyArray[2]}{$keyArray[3]}{$keyArray[4]} = $field; 
      break; 
    } 
} 

这是一个有点笨重,但它的工作原理。 $multiDimensional最终结构遵循HTML名称属性的结构。如果有人知道如何用Javascript做类似的事情,我很乐意听到它!