javascript - получить - данные формы в json




Преобразование данных формы в объект JavaScript с помощью jQuery (20)

При всем заданном ответе есть какая-то проблема, которая ...

Если введите имя как массив, например name[key] , но он будет генерироваться так

 name:{
   key : value
 }

Например: если у меня есть такая форма.

    <form>
        <input name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" >
    </form>

Затем он будет генерировать объект таким образом со всем предоставленным ответом.

Object {
    name : 'value',
    name1[key1] : 'value1',
    name2[key2] : 'value2',
    name3[key3] : 'value3', 
}

Но он должен генерировать, как показано ниже, каждый хочет сделать это, как показано ниже.

Object {
    name : 'value',
    name1 : {
        key1 : 'value1'
    },
    name2 : {
        key2 : 'value2'
    },
    name3 : {
        key2 : 'value2'
    }
}

Затем попробуйте выполнить это ниже кода js.

(function($){
    $.fn.getForm2obj = function(){
        var _ = {},_t=this;
        this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
        this.b = function(k,v,a = 0){ if(a) eval(k+".push("+v+");"); else eval(k+"="+v+";"); };
        $.map(this.serializeArray(),function(n){
            if(n.name.indexOf('[') > -1 ){
                var keys = n.name.match(/[a-zA-Z0-9_]+|(?=\[\])/g),le = Object.keys(keys).length,tmp = '_';
                $.map(keys,function(key,i){
                    if(key == ''){
                        eval("ale = Object.keys("+tmp+").length;");
                        if(!ale) _t.b(tmp,'[]');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'",1);
                        else _t.b(tmp += "["+ale+"]",'{}');
                    }else{
                        _t.c(tmp += "['"+key+"']",'{}');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'");
                    }
                });
            }else _t.b("_['"+n['name']+"']","'"+n['value']+"'");
        });
        return _;
    }
})(jQuery);
console.log($('form').getForm2obj());
<!DOCTYPE html><html><head>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <title>Convert form data to JavaScript object with jQuery</title>
</head>
<body>
    <form>
        <input name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" >
        <input type="checkbox" name="name4[]" value="1" checked="checked">
        <input type="checkbox" name="name4[]" value="2">
        <input type="checkbox" name="name4[]" value="3">
    </form>
</body></html>

Как преобразовать все элементы моей формы в объект JavaScript?

Я хотел бы иметь способ автоматического создания объекта JavaScript из моей формы, без необходимости перебирать каждый элемент. Мне не нужна строка, возвращаемая $('#formid').serialize(); , и я не хочу, чтобы карта возвращалась $('#formid').serializeArray();


Конвертировать формы в JSON LIKE THE BOSS

Текущий источник находится на GitHub и беседке.

$ bower install jquery-serialize-object

Следующий код теперь устарел .

Следующий код может работать со всеми типами имен ввода; и обрабатывать их так, как вы ожидали.

Например:

<!-- all of these will work! -->
<input name="honey[badger]" value="a">
<input name="wombat[]" value="b">
<input name="hello[panda][]" value="c">
<input name="animals[0][name]" value="d">
<input name="animals[0][breed]" value="e">
<input name="crazy[1][][wonky]" value="f">
<input name="dream[as][vividly][as][you][can]" value="g">
// output
{
  "honey":{
    "badger":"a"
  },
  "wombat":["b"],
  "hello":{
    "panda":["c"]
  },
  "animals":[
    {
      "name":"d",
      "breed":"e"
    }
  ],
  "crazy":[
    null,
    [
      {"wonky":"f"}
    ]
  ],
  "dream":{
    "as":{
      "vividly":{
        "as":{
          "you":{
            "can":"g"
          }
        }
      }
    }
  }
}

использование

$('#my-form').serializeObject();

Волшебство (JavaScript)

(function($){
    $.fn.serializeObject = function(){

        var self = this,
            json = {},
            push_counters = {},
            patterns = {
                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
                "key":      /[a-zA-Z0-9_]+|(?=\[\])/g,
                "push":     /^$/,
                "fixed":    /^\d+$/,
                "named":    /^[a-zA-Z0-9_]+$/
            };


        this.build = function(base, key, value){
            base[key] = value;
            return base;
        };

        this.push_counter = function(key){
            if(push_counters[key] === undefined){
                push_counters[key] = 0;
            }
            return push_counters[key]++;
        };

        $.each($(this).serializeArray(), function(){

            // skip invalid keys
            if(!patterns.validate.test(this.name)){
                return;
            }

            var k,
                keys = this.name.match(patterns.key),
                merge = this.value,
                reverse_key = this.name;

            while((k = keys.pop()) !== undefined){

                // adjust reverse_key
                reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');

                // push
                if(k.match(patterns.push)){
                    merge = self.build([], self.push_counter(reverse_key), merge);
                }

                // fixed
                else if(k.match(patterns.fixed)){
                    merge = self.build([], k, merge);
                }

                // named
                else if(k.match(patterns.named)){
                    merge = self.build({}, k, merge);
                }
            }

            json = $.extend(true, json, merge);
        });

        return json;
    };
})(jQuery);

Вы можете сделать это:

var frm = $(document.myform);
var data = JSON.stringify(frm.serializeArray());

См. JSON .


Если вы используете Underscore.js вы можете использовать относительно краткий:

_.object(_.map($('#myform').serializeArray(), _.values))

Использование:

function form_to_json (selector) {
  var ary = $(selector).serializeArray();
  var obj = {};
  for (var a = 0; a < ary.length; a++) obj[ary[a].name] = ary[a].value;
  return obj;
}

Выход:

{"myfield": "myfield value", "passwordfield": "mypasswordvalue"}

Используя решение maček , я изменил его, чтобы работать с тем, как ASP.NET MVC обрабатывает свои вложенные / сложные объекты в одной и той же форме. Все, что вам нужно сделать, это изменить часть проверки на это:

"validate": /^[a-zA-Z][a-zA-Z0-9_]*((?:\[(?:\d*|[a-zA-Z0-9_]+)\])*(?:\.)[a-zA-Z][a-zA-Z0-9_]*)*$/,

Это будет соответствовать, а затем правильно отображать элементы с такими именами, как:

<input type="text" name="zooName" />

А также

<input type="text" name="zooAnimals[0].name" />

Нет никакого способа сделать это, не исследуя каждый из элементов. То, что вы действительно хотите знать, «кто-то еще уже написал метод, который преобразует форму в объект JSON?» Что-то вроде следующего должно работать - обратите внимание, что он даст вам только элементы формы, которые будут возвращены через POST (должно иметь имя). Это не проверено .

function formToJSON( selector )
{
     var form = {};
     $(selector).find(':input[name]:enabled').each( function() {
         var self = $(this);
         var name = self.attr('name');
         if (form[name]) {
            form[name] = form[name] + ',' + self.val();
         }
         else {
            form[name] = self.val();
         }
     });

     return form;
}

Однострочный (без зависимостей, кроме jQuery) использует привязку фиксированного объекта для функции, переданной методу map .

$('form').serializeArray().map(function(x){this[x.name] = x.value; return this;}.bind({}))[0]

Что оно делает?

"id=2&value=1&comment=ok" => Object { id: "2", value: "1", comment: "ok" }

подходит для прогрессивных веб-приложений (можно легко поддерживать как регулярное представление формы, так и аякс-запросы)



У меня была такая же проблема в последнее время и вышла с этим плагином jQuery .toJSON, который преобразует форму в объект JSON с той же структурой. Это также чрезвычайно полезно для динамически создаваемых форм, где вы хотите, чтобы ваш пользователь добавлял больше полей в определенные места.

Дело в том, что вы действительно можете создать форму, чтобы она имела структуру, поэтому, допустим, вы хотите создать форму, в которой пользователь вставляет свои любимые места в город: вы можете представить эту форму для представления <places>...</places> XML-элемент, содержащий список мест, которым пользователь любит, таким образом, список элементов <place>...</place> каждый из которых содержит, например, элемент <name>...</name> , <type>...</type> а затем список элементов <activity>...</activity> для представления действий, которые вы можете выполнять в таком месте. Таким образом, ваша структура XML будет выглядеть так:

<places>

    <place>

        <name>Home</name>
        <type>dwelling</type>

        <activity>sleep</activity>
        <activity>eat</activity>
        <activity>watch TV</activity>

    </place>

    <place>...</place>

    <place>...</place>

</places>

Как здорово было бы иметь объект JSON из этого, который будет представлять эту точную структуру, чтобы вы могли:

  • Храните этот объект так, как он есть в любой базе данных CouchDB
  • Прочтите его со стороны сервера $ _POST [] и извлеките правильно вложенный массив, который вы можете затем семантически манипулировать
  • Используйте некоторый скрипт на стороне сервера, чтобы преобразовать его в хорошо сформированный XML-файл (даже если вы не знаете его точной структуры a-priori)
  • Просто как-то используйте его, как в любом сценарии сервера Node.js

Итак, теперь нам нужно подумать, как форма может представлять XML-файл.

Конечно, <form>тег есть root, но тогда у нас есть тот <place>элемент, который является контейнером, а не самим элементом данных, поэтому мы не можем использовать для него тег ввода.

Вот где <fieldset>тег пригодится! Мы будем использовать <fieldset>теги для представления всех элементов контейнера в нашем представлении формы / XML и поэтому получаем такой результат:

<form name="places">

    <fieldset name="place">

        <input type="text" name="name"/>
        <select name="type">
            <option value="dwelling">Dwelling</option>
            <option value="restoration">Restoration</option>
            <option value="sport">Sport</option>
            <option value="administrative">Administrative</option>
        </select>

        <input type="text" name="activity"/>
        <input type="text" name="activity"/>
        <input type="text" name="activity"/>

    </fieldset>

</form>

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

На этом этапе вы можете увидеть, name="array[]"как внутри формы нет такого имени, и все довольно, просто и семантически.

Теперь мы хотим, чтобы эта форма была преобразована в объект JSON, который будет выглядеть следующим образом:

{'places':{

    'place':[

        {

            'name': 'Home',
            'type': 'dwelling',

            'activity':[

                 'sleep',
                 'eat',
                 'watch TV'

            ]

        },

        {...},

        {...}

    ]

}}

Для этого я разработал этот плагин jQuery, в котором кто-то помог оптимизировать этот поток Code Review и выглядит так:

$.fn.toJSO = function () {
    var obj = {},
        $kids = $(this).children('[name]');
    if (!$kids.length) {
        return $(this).val();
    }
    $kids.each(function () {
        var $el = $(this),
            name = $el.attr('name');
        if ($el.siblings("[name=" + name + "]").length) {
            if (!/radio|checkbox/i.test($el.attr('type')) || $el.prop('checked')) {
                obj[name] = obj[name] || [];
                obj[name].push($el.toJSO());
            }
        } else {
            obj[name] = $el.toJSO();
        }
    });
    return obj;
};

Я также сделал это одно сообщение в блоге, чтобы объяснить это больше.

Это преобразует все в форме в JSON (даже радио и флажки), и все, что вам осталось сделать, это позвонить

$.post('script.php',('form').toJSO(), ...);

Я знаю, что есть много способов конвертировать формы в объекты JSON, .serialize()и .serializeArray()в большинстве случаев они работают отлично и в основном предназначены для использования, но я думаю, что вся эта идея написания формы как структуры XML со значимыми именами и преобразования ее в хорошо сформированный объект JSON стоит попробовать, а также тот факт, что вы можете добавлять теги ввода с одним именем без особого беспокойства, очень полезно, если вам нужно извлекать данные с динамически генерируемыми формами.

Я надеюсь, что это помогает кому-то!


Хорошо, я знаю, что это уже имеет очень высокий ответ, но недавно был задан другой подобный вопрос , и я тоже был обращен к этому вопросу. Я также хотел бы предложить свое решение, потому что оно дает преимущество перед принятым решением: вы можете включать отключенные элементы формы (что иногда важно, в зависимости от того, как работают ваши пользовательские интерфейсы)

Вот мой ответ от другого вопроса :

Первоначально мы использовали метод serializeArray() jQuery, но это не включает элементы формы, которые отключены. Мы часто будем отключать элементы формы, которые «синхронизируются» с другими источниками на странице, но нам все равно нужно включать данные в наш сериализованный объект. Поэтому serializeArray() отсутствует. Мы использовали селектор :input для получения всех входных элементов (как включенных, так и отключенных) в данном контейнере, а затем $.map() для создания нашего объекта.

var inputs = $("#container :input");
var obj = $.map(inputs, function(n, i)
{
    var o = {};
    o[n.name] = $(n).val();
    return o;
});
console.log(obj);

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

Это на самом деле немного изменилось из того, что мы использовали. Нам нужно было создать объект, который был структурирован как .NET IDictionary, поэтому мы использовали это: (я предоставляю его здесь, если это полезно)

var obj = $.map(inputs, function(n, i)
{
    return { Key: n.name, Value: $(n).val() };
});
console.log(obj);

Мне нравятся оба этих решения, потому что они - простое использование функции $.map() , и у вас есть полный контроль над вашим селектором (так, какие элементы вы в конечном итоге включаете в свой результирующий объект). Кроме того, дополнительный плагин не требуется. Обычный старый jQuery.


Что случилось с:

var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;}); 

Я нашел проблему с выбранным решением.

При использовании форм с именами на основе массива функция jQuery serializeArray () фактически умирает.

У меня есть фреймворк PHP, который использует имена полей на основе массива, чтобы одна и та же страница могла быть помещена на одну и ту же страницу несколько раз в нескольких представлениях. Это может быть удобно помещать как добавление, редактирование и удаление на одной странице без противоречивых моделей форм.

Поскольку я хотел серализовать формы без необходимости использовать эту абсолютную базовую функциональность, я решил написать свой собственный seralizeArray ():

        var $vals = {};

        $("#video_edit_form input").each(function(i){
            var name = $(this).attr("name").replace(/editSingleForm\[/i, '');

            name = name.replace(/\]/i, '');

            switch($(this).attr("type")){
                case "text":
                    $vals[name] = $(this).val();
                    break;
                case "checkbox":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                case "radio":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                default:
                    break;
            }
        });

Обратите внимание: это также работает вне формы submit (), поэтому, если в остальной части вашего кода будет возникать ошибка, форма не будет отправлена, если вы разместите на кнопке ссылки «Сохранить изменения».

Также обратите внимание, что эта функция никогда не должна использоваться для проверки формы только для сбора данных для отправки на сервер для проверки. Использование такого слабого и массового кода приведет к XSS и т. Д.


Я нашел проблему с кодом Тобиаса Коэна (у меня недостаточно очков, чтобы прокомментировать это напрямую), что в противном случае работает для меня. Если у вас есть два варианта выбора с тем же именем, оба со значением = "", исходный код будет генерировать «имя»: вместо «name»: ["", ""]

Я думаю, что это можно зафиксировать, добавив «|| o [this.name] == '» в первое условие if:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] || o[this.name] == '') {
            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;
};

самый простой и самый точный способ, который я нашел для этой проблемы, - использовать плагин bbq или этот (размер около 0,5 КБ).

он также работает с многомерными массивами.

$.fn.serializeObject = function()
{
	return $.deparam(this.serialize());
};


serializeArray уже делает именно это. Вам просто нужно массировать данные в требуемом формате:

function objectifyForm(formArray) {//serialize data function

  var returnArray = {};
  for (var i = 0; i < formArray.length; i++){
    returnArray[formArray[i]['name']] = formArray[i]['value'];
  }
  return returnArray;
}

Следите за скрытыми полями, которые имеют то же имя, что и реальные входы, поскольку они будут перезаписаны.


Другой ответ

document.addEventListener("DOMContentLoaded", function() {
  setInterval(function() {
    var form = document.getElementById('form') || document.querySelector('form[name="userprofile"]');
    var json = Array.from(new FormData(form)).map(function(e,i) {this[e[0]]=e[1]; return this;}.bind({}))[0];
    
    console.log(json)
    document.querySelector('#asJSON').value = JSON.stringify(json);
  }, 1000);
})
<form name="userprofile" id="form">
  <p>Name <input type="text" name="firstname" value="John"/></p>
  <p>Family name <input name="lastname" value="Smith"/></p>
  <p>Work <input name="employment[name]" value="inc, Inc."/></p>
  <p>Works since <input name="employment[since]" value="2017" /></p>
  <p>Photo <input type="file" /></p>
  <p>Send <input type="submit" /></p>
</form>

JSON: <textarea id="asJSON"></textarea>

FormData: https://developer.mozilla.org/en-US/docs/Web/API/FormData


Я бы не использовал это на реальном сайте из-за атак XSS и, вероятно, много других проблем, но вот краткий пример того, что вы могли бы сделать:

$("#myform").submit(function(){
    var arr = $(this).serializeArray();
    var json = "";
    jQuery.each(arr, function(){
        jQuery.each(this, function(i, val){
            if (i=="name") {
                json += '"' + val + '":';
            } else if (i=="value") {
                json += '"' + val.replace(/"/g, '\\"') + '",';
            }
        });
    });
    json = "{" + json.substring(0, json.length - 1) + "}";
    // do something with json
    return false;
});

Мне нравится версия для самуллов, но я считаю, что у нее небольшая ошибка. Обычно JSON отправляется как

{ "CoreSKU": "PCGUYJS", "name_de": "все", ...

НЕ как

[{ "CoreSKU": "PCGUYJS"}, { "name_de": "все"}, ...

поэтому функция IMO должна читать:

App.toJson = function( selector ) {
    var o = {};
    $.map( $( selector ), function( n,i )
    {
        o[n.name] = $(n).val();
    });     
    return o;
}

и обернуть его в массив данных (как и обычно ожидается), и, наконец, отправить его как astring App.stringify ({data: App.toJson ('#cropform: input')})

Для строкового взгляда на вопрос 3593046 для скудной версии, в json2.js для каждой версии, охватывающей все версии. Это должно покрыть все это :)


Я сам кодировал форму для многомерного JavaScript-объекта, чтобы использовать ее в процессе производства. Результатом этого является https://github.com/serbanghita/formToObject.js .







serialization