2012-06-20 16 views
7

Mam formularza na mojej stronie jak poniżej:jquery input serialize z tablicami

<form id="myform" action="" method=""> 
<input type="text" name="name[1][first]"> 
<input type="text" name="name[2][first]"> 
<input type="text" name="name[3][first]"> 
</form> 

Chcę po prostu złapać wszystkie dane i przesyła je do usługa więc mieć ten JS:

$fields = $('#myform').serializeArray(); 

Problem polega na tym, że tworzy json ze wszystkimi nawiasami wyświetlanymi w nazwach wejściowych, więc pojawia się błąd analizy.

Jak mogę użyć serializeArray i uzyskać właściwy json?

Powstały format, który chciałbym zobaczyć coś takiego:

{ 
    "name": { 
    "1": { 
     "first": "val1" 
    }, 
    "2": { 
     "first": "val2" 
    }, 
    "3": { 
     "first": "val3" 
    } 
    } 
} 

Dzięki!

+8

10 pytań, 0% zaakceptowanych odpowiedzi. – pete

+1

Będziesz musiał zmienić nazwy swoich wejść. Serializator JSON nie wymyśli dla nich odpowiednich nazw. –

Odpowiedz

0

Zważywszy, że udało Ci się w odcinkach tablicę do $fields, można teraz przejść przez to i przekonwertować go na bardziej łatwo trawieniu obiektu Wynik:

var result = {}; 
for(var i in $fields) { 
    var parts = $fields[i].name.split("["); 
    var resultIndex = parseInt(parts[1].replace(']', ''), 10); 
    result[resultIndex] = $fields[i].value; 
} 

Podczas $fields jest poprawną nazwą zmiennej globalnej, Nie mogę o tym powiedzieć: w JavaScript zmienne lokalne są zdefiniowane słowem kluczowym var i nie mają przed sobą znaku dolara - znak dolara zwykle odnosi się do obiektu jQuery. W rezultacie można pobrać pola powołując:

var fields = $('#myform').serializeArray(); 
+0

Nazwa zmiennej nie ma znaczenia., A także to, czy jest globalna, czy nie jest związana z pytaniem. –

+0

To był tylko literówka z mojej strony podczas pisania pytania. To PHP we mnie wychodzi. – user989557

+0

Jak mogę to uruchomić, gdy formularz ma również inne dane wejściowe? Kiedy dodaję wejścia takie jak: Otrzymuję błąd js, że części [1] są niezdefiniowane. Zakładam, że dzieje się tak dlatego, że próbuje on parsować elementy bez nawiasów. – user989557

9

zrobiłem rekurencyjnych funkcji/plugin zrobić dokładnie to:

$.fn.serializeControls = function() { 
 
    var data = {}; 
 

 
    function buildInputObject(arr, val) { 
 
    if (arr.length < 1) 
 
     return val; 
 
    var objkey = arr[0]; 
 
    if (objkey.slice(-1) == "]") { 
 
     objkey = objkey.slice(0,-1); 
 
    } 
 
    var result = {}; 
 
    if (arr.length == 1){ 
 
     result[objkey] = val; 
 
    } else { 
 
     arr.shift(); 
 
     var nestedVal = buildInputObject(arr,val); 
 
     result[objkey] = nestedVal; 
 
    } 
 
    return result; 
 
    } 
 

 
    $.each(this.serializeArray(), function() { 
 
    var val = this.value; 
 
    var c = this.name.split("["); 
 
    var a = buildInputObject(c, val); 
 
    $.extend(true, data, a); 
 
    }); 
 
    
 
    return data; 
 
} 
 

 
$("#output").html(JSON.stringify($('#myform').serializeControls(), null, 2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 

 
<form id="myform" action="" method=""> 
 
<input type="text" name="name[1][first]" value="beep"> 
 
<input type="text" name="name[1][second]" value="bloop"> 
 
<input type="text" name="name[2][first]" value="derp"> 
 
    
 
<input type="text" name="foo" value="bar"> 
 
</form> 
 

 
<pre id="output"> 
 
</pre>

Można również zadzwonić go na inny selektory oprócz całego form. Na przykład wywołanie:

$('input[name^="name\\["]').serializeControls()

zwróci obiekt zawierający tylko pola name. Aby uzyskać więcej przykładów, zobacz artykuł http://codepen.io/alexweissman/pen/MyWZdN.

Należy pamiętać, że (na razie) to nie będzie działać dla nazw pól z pustymi nawiasami (na przykład pola takie jak input name="potatoes[]" zostaną zignorowane, ponieważ nie można wyodrębnić klucza niepowtarzalnego).

+1

To jest as.Próbowałem wtyczki jquery-serialize-object, która nie działała, ale tak się dzieje. Śliczny. –

+0

Witaj, twój kod wydaje się nie serializować poprawnie '': 'var val = this.value;' zwraca tylko pierwszą wybraną wartość (testowane na firefox). Ponieważ jest to hack dla jquery, myślę, że można to naprawić łatwo za pomocą '$ (this) .val()'. – Asenar

0

Oto wersja kodu alexw, który działa dla nazw pól z pustymi nawiasami. Umożliwia to zarządzanie polami z wieloma wartościami (pola wyboru, wybierz wiele).

$j.fn.serializeObject = function() { 
    var data = {}; 

    function buildInputObject(arr, val) { 
     if (arr.length < 1) { 
      return val; 
     } 
     var objkey = arr[0]; 
     if (objkey.slice(-1) == "]") { 
      objkey = objkey.slice(0,-1); 
     } 
     var result = {}; 
     if (arr.length == 1){ 
      result[objkey] = val; 
     } else { 
      arr.shift(); 
      var nestedVal = buildInputObject(arr,val); 
      result[objkey] = nestedVal; 
     } 
     return result; 
    } 

    function gatherMultipleValues(that) { 
     var final_array = []; 
     $j.each(that.serializeArray(), function(key, field) { 
      // Copy normal fields to final array without changes 
      if(field.name.indexOf('[]') < 0){ 
       final_array.push(field); 
       return true; // That's it, jump to next iteration 
      } 

      // Remove "[]" from the field name 
      var field_name = field.name.split('[]')[0]; 

      // Add the field value in its array of values 
      var has_value = false; 
      $j.each(final_array, function(final_key, final_field){ 
       if(final_field.name === field_name) { 
        has_value = true; 
        final_array[ final_key ][ 'value' ].push(field.value); 
       } 
      }); 
      // If it doesn't exist yet, create the field's array of values 
      if(! has_value) { 
       final_array.push({ 'name': field_name, 'value': [ field.value ] }); 
      } 
     }); 
     return final_array; 
    } 

    // Manage fields allowing multiple values first (they contain "[]" in their name) 
    var final_array = gatherMultipleValues(this); 

    // Then, create the object 
    $j.each(final_array, function() { 
     var val = this.value; 
     var c = this.name.split('['); 
     var a = buildInputObject(c, val); 
     $j.extend(true, data, a); 
    }); 

    return data; 
};