Сериализация сложной формы в объект JSON с помощью jQuery

Я искал несколько часов и не нашел ответа. Пожалуйста, прочитайте весь вопрос, прежде чем флеймить! :)

у меня есть форма следующего вида:

<form id="sample">
 <input name="name" type="text" value="name value" />

 <input name="phone[0][type]" type="text" value="cell" />
 <input name="phone[0][number]" type="text" value="000" />

 <input name="phone[1][type]" type="text" value="home" />
 <input name="phone[1][number]" type="text" value="111" />
</form>

и нужно иметь возможность сериализовать его до этого:

{
 name: 'name value',

 phone: [
  {
   type: 'cell',
   number: '000'
  },
  {
   type: 'home',
   number: '111'
  }
 ]
}

Я пробовал большинство ответов на SO, включая библиотеки jquery-json, и большинство из них возвращают что-то вроде этого:

{
 'name': 'name value',
 'phone[0][type]': 'cell',
 'phone[0][number]': '000',
 'phone[1][type]': 'home',
 'phone[1][number]': '111',
}

Это нечто я не могу использовать! : P

спасибо все вперед.

6 ответов


попробуйте этот код, который я написал для вас... Отлично работает для меня, просто используя ваш результат данных. Вы можете работать над этим и сделать простой плагин jQuery...

образец нужен JSON.stringify для полной работы.

var d = {
    'name': 'name value',
    'phone[0][type]': 'cell',
    'phone[0][number]': '000',
    'phone[1][type]': 'home',
    'phone[1][number]': '111',
};

$(document).ready(function(){

    arrangeJson(d);
    alert(JSON.stringify(d));
});

function arrangeJson(data){
    var initMatch = /^([a-z0-9]+?)\[/i;
    var first = /^\[[a-z0-9]+?\]/i;
    var isNumber = /^[0-9]$/;
    var bracers = /[\[\]]/g;
    var splitter = /\]\[|\[|\]/g;

    for(var key in data) {
        if(initMatch.test(key)){
            data[key.replace(initMatch,'[][')] = data[key];
        }
        else{
            data[key.replace(/^(.+)$/,'[]')] = data[key];
        }
        delete data[key];
    }


    for (var key in data) {
        processExpression(data, key, data[key]);
        delete data[key];
    }

    function processExpression(dataNode, key, value){
        var e = key.split(splitter);
        if(e){
            var e2 =[];
            for (var i = 0; i < e.length; i++) {
                    if(e[i]!==''){e2.push(e[i]);} 
            }
            e = e2;
            if(e.length > 1){
                var x = e[0];
                var target = dataNode[x];
                if(!target){
                    if(isNumber.test(e[1])){
                        dataNode[x] = [];
                    }
                    else{
                        dataNode[x] ={}
                    }
                }
                processExpression(dataNode[x], key.replace(first,''), value);
            }
            else if(e.length == 1){
                dataNode[e[0]] = value;
            }
            else{
                alert('This should not happen...');
            }
        }
    }
}

существует также следующая библиотека

http://code.google.com/p/form2js/


Это очень хорошо для меня. Это не должно иметь библиотеку form2js.

$.fn.serializeObject = function serializeObject() {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function () {
            if (o[this.name] !== undefined) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };

для сериализации данных формы я использовал этот код.

JSON.stringify($(this).serializeObject());//'this' points to the form

Если у вас есть какие-либо сомнения, пожалуйста, не стесняйтесь добавлять комментарий.


С этой структурой я не думаю, что любая библиотека JSON может выполнять всю работу. Итак, я думаю, что проще написать наш собственный цикл преобразования.

вот код для вашей сериализации:http://jsfiddle.net/7MAUv/1/

логика довольно проста, секрет в eval для запуска строк, таких как динамические команды. Я старался сделать это как можно проще, почти все строки комментируются.

BTW, чувствует свободным сделать вопросы.


Это не совсем то, что вы просили, но если вы используете библиотеку jQuery и вам нужна сложная форма, сериализованная с целью отправки ее в ajax, вы можете использовать sth как это

ajaxRunning = $.ajax(
   "?"+$('#yourForm').serialize(),
    {
       data: {
           anotherData: 'worksFine',
           etc: 'still works'
       },
       success: function(result) {
           doSth();
       },
       dataType: "json"
});

вы можете использовать в $.почта и.$ вам так же

кафе!


другая библиотека, которая решает эту проблему, -С помощью jQuery.serializeJSON Марио Молина. Он работает и расширяет jQuery.