2013-07-10 35 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做類似的事情,我很樂意聽到它!