2013-10-28 121 views
5

如何將HTML表單數據連續化到關聯數組而不是使用jQuery生成的$ .serializeArray()生成的數字索引格式?JQuery - 將表單數據序列化到關聯數組

通過jQuery.serializeArray給出的輸出使得使用數字索引鍵它難以直接選擇值,當複選框中形式的輸入中使用,可能會發生輕微的指數移動..

serializeArray

的輸出
[ 
    0: [name: 'field-1', value: 'val1'], 
    1: [name: 'check', value: 'val2'], 
    2: [name: 'check', value: 'val3'] 
] 

所需的輸出 - 更可靠的格式和簡單價值訪問

[ 
    'field-1' : 'val1', 
    'check' : [ 0 : 'val2', 1 : 'val3' ] 
] 
+0

與格式y的樣品更新ou得到和所需的格式。 –

+2

這對我來說似乎是一個非常好的問題,我相信它應該重新打開。 –

+0

重新打開這個問題,我想知道同樣的事情 – IcedDante

回答

7

我工作的解決方案是編寫我自己的jQuery函數$ .serializeAssoc()和$ .serializeObject(),它們也可以處理表單上多選選項的多維數組。

這兩個函數各有利弊, 我使用serializeAssoc來簡化直接泛型值訪問的表單數據,通常在JS驗證中。

serializeObject使用自定義數字鍵索引可以方便地使用多功能表單,簡化數據配對從複雜表單設置多選字段或表單中提交的信息使用DOM構建的值,其中表單中的數據具有父級和子女關係,serializeAssoc不能很好地處理。

serializeAssoc

以下功能允許長度檢查,但呈現的自定義數字鍵索引的問題,在提交陣列中的一個AJAX調用它會導致指數的填充

$.fn.serializeAssoc = function() { 
    var data = {}; 
    $.each(this.serializeArray(), function(key, obj) { 
    var a = obj.name.match(/(.*?)\[(.*?)\]/); 
    if(a !== null) 
    { 
     var subName = a[1]; 
     var subKey = a[2]; 

     if(!data[subName]) { 
     data[subName] = [ ]; 
     } 

     if (!subKey.length) { 
     subKey = data[subName].length; 
     } 

     if(data[subName][subKey]) { 
     if($.isArray(data[subName][subKey])) { 
      data[subName][subKey].push(obj.value); 
     } else { 
      data[subName][subKey] = [ ]; 
      data[subName][subKey].push(obj.value); 
     } 
     } else { 
     data[subName][subKey] = obj.value; 
     } 
    } else { 
     if(data[obj.name]) { 
     if($.isArray(data[obj.name])) { 
      data[obj.name].push(obj.value); 
     } else { 
      data[obj.name] = [ ]; 
      data[obj.name].push(obj.value); 
     } 
     } else { 
     data[obj.name] = obj.value; 
     } 
    } 
    }); 
    return data; 
}; 

serializeObject

下面的以下功能允許自定義數字索引,而不會導致填充,但會阻止長度檢查。如果需要,使用每個循環檢查索引鍵計數。如果在AJAX調用中提交對象,則必須先使用JSON.Stringify並將var中的值傳遞給解碼服務器端,因爲直接使用會在某些瀏覽器中導致意外的行結束錯誤。

$.fn.serializeObject = function() { 
    var data = {}; 
    $.each(this.serializeArray(), function(key, obj) { 
     var a = obj.name.match(/(.*?)\[(.*?)\]/); 
     if(a !== null) 
     { 
      var subName = new String(a[1]); 
      var subKey = new String(a[2]); 
      if(!data[subName]) { 
       data[subName] = { }; 
       data[subName].length = 0; 
      }; 
      if (!subKey.length) { 
       subKey = data[subName].length; 
      } 
      if(data[subName][subKey]) { 
       if($.isArray(data[subName][subKey])) { 
       data[subName][subKey].push(obj.value); 
       } else { 
       data[subName][subKey] = { }; 
       data[subName][subKey].push(obj.value); 
       }; 
      } else { 
       data[subName][subKey] = obj.value; 
      }; 
      data[subName].length++; 
     } else { 
      var keyName = new String(obj.name); 
      if(data[keyName]) { 
       if($.isArray(data[keyName])) { 
        data[keyName].push(obj.value); 
       } else { 
        data[keyName] = { }; 
        data[keyName].push(obj.value); 
       }; 
      } else { 
       data[keyName] = obj.value; 
      }; 
     }; 
    }); 
    return data; 
}; 

用法:

添加功能

<script> 
    (function($){ 
    $.fn.serializeAssoc = function() { 
     ... As Presented Above ... 
    }; 
    $.fn.serializeObject = function() { 
     ... As Presented Above ... 
    }; 
    })(jQuery); 
</script> 

表格樣本

<form id="myForm"> 
    <input type="text" name="myName" /> 

    <select name="consoles" multiple> 
    <option selected>PC</option> 
    <option selected>XBOX 360</option> 
    <option selected>PS3</option> 
    </select> 

    <input type="text" name="sample[100]" value="Mario" /> 
    <input type="text" name="sample[101]" value="Brothers" /> 

    <input type="submit" name="submit" value="Submit" /> 
</form> 

使用功能

<script> 
    (function($) { 
    $('#myForm').submit(function(e){ 
     e.preventDefault(); 
     var formData = $('#myForm').serializeAssoc(); 
     console.log(formData); 
    }); 
    })(jQuery); 
</script> 

動態形式示例

<form id="myForm"> 
    <input type="text" name="myName" value="Spuggy" /> 

    <div id="characters"> 
    <input type="text" name="character[]" value="Mario" /> 
    <input type="text" name="character[]" value="Sonic" /> 
    </div> 

    <div id="consoles"> 
    <input type="text" name="console[xbox]" value="XBOX One" /> 
    <input type="text" name="console[playstation]" value="PlayStation 4" /> 
    </div> 

    <input type="submit" name="submit" value="Submit" /> 
</form> 

<script> 
    (function($) { 
    $('#myForm').submit(function(e){ 
     e.preventDefault(); 
     var formData = $('#myForm').serializeAssoc(); 
     console.log(formData); 
    }); 
    })(jQuery); 
</script> 

動態形式輸出

[ 
    myName: 'Spuggy', 
    character: [ 
    0: 'Mario', 
    1: 'Sonic' 
    ], 
    console: [ 
    'xbox': 'XBOX One', 
    'playstation': 'PlayStation 4' 
    ] 
] 
+0

它運行良好,但如果我有一個'name =「複選框[20] []」',它會在添加第20個數組之前在數組中創建19個空值。這是預期的行爲? –

+0

是的,兩個函數中的一個是數字填充會發生,它不應該與兩個都做,一個應該與您的案例一起工作,如果不是,我可以在幾天內從旅行中返回來看看它。 它應該發生在serializeAssoc但不是serializeObject –

+0

如果它是serializeObject你在哪裏使用和體驗過填充,請嘗試更改var data = {};到var data = []; –