Сериализация сложной формы в объект JSON с использованием jQuery - PullRequest
20 голосов
/ 09 сентября 2010

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

У меня есть форма, подобная этой:

<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 ]

19 голосов
/ 09 сентября 2010

Попробуйте этот код, который я написал для вас ... Хорошо работает для меня, просто используя ваши данные результата.Вы можете поработать над этим и создать простой плагин 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,'[$1][')] = data[key];
        }
        else{
            data[key.replace(/^(.+)$/,'[$1]')] = 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...');
            }
        }
    }
}
6 голосов
/ 23 февраля 2011

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

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

2 голосов
/ 27 декабря 2013

Это сработало очень хорошо для меня. Для этого не нужно иметь библиотеку 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

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

1 голос
/ 09 сентября 2010

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

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

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

Кстати, не стесняйтесь задавать вопросы.

0 голосов
/ 14 мая 2016

Еще одна библиотека, решающая эту проблему, - jquery.serializeJSON , автор Mario Izquierdo. Работает и расширяет jQuery.

0 голосов
/ 01 сентября 2014

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

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

, вы можетеиспользуйте также в $ .post и $ .get

nJoy!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...