我正在创建一个表单数据序列化函数,它通过AJAX将信息传递给PHP文件以进行错误检查和解析。我知道我可以在技术上使用JQuery中的.serialize()
方法,但我需要更多地控制我的数据。基本上我想将我的表单中的字段解析为多维Javascript对象,然后转换为JSON以通过AJAX发送。我已经建立了一个大部分都有效的方法,但仍然存在一些缺陷。这是我的Javascript / JQuery代码:
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属性很简单,如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 :(得分:0)
尝试正确初始化临时变量。例如:
var tempObj = [];
现在,您实际上正在创建通过每次迭代重用的全局变量。
答案 1 :(得分: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 name属性结构的结构。如果有人知道如何在Javascript中做类似的事情,我很乐意听到它!