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

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

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

1446
задан Yisroel 26 июля '09 в 16:39
источник поделиться

51 ответ

  • 1
  • 2

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;
}

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

1552
ответ дан Tobias Cohen 27 июля '09 в 6:38
источник поделиться

Преобразование форм в JSON LIKE A BOSS


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

$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);
408
ответ дан maček 07 дек. '11 в 1:25
источник поделиться

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

var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;}); 
255
ответ дан mkschreder 22 июля '13 в 12:59
источник поделиться

Фиксированная версия решения Тобиаса Коэна. Он правильно обрабатывает значения фальши, такие как 0 и ''.

jQuery.fn.serializeObject = function() {
  var arrayData, objectData;
  arrayData = this.serializeArray();
  objectData = {};

  $.each(arrayData, function() {
    var value;

    if (this.value != null) {
      value = this.value;
    } else {
      value = '';
    }

    if (objectData[this.name] != null) {
      if (!objectData[this.name].push) {
        objectData[this.name] = [objectData[this.name]];
      }

      objectData[this.name].push(value);
    } else {
      objectData[this.name] = value;
    }
  });

  return objectData;
};

И версия CoffeeScript для удобства кодирования:

jQuery.fn.serializeObject = ->
  arrayData = @serializeArray()
  objectData = {}

  $.each arrayData, ->
    if @value?
      value = @value
    else
      value = ''

    if objectData[@name]?
      unless objectData[@name].push
        objectData[@name] = [objectData[@name]]

      objectData[@name].push value
    else
      objectData[@name] = value

  return objectData
97
ответ дан Daniel X Moore 05 марта '11 в 1:28
источник поделиться

Мне нравится использовать Array.prototype.reduce, потому что это однострочный, и он не полагается на Underscore.js или тому подобное:

$('#formid').serializeArray()
    .reduce(function(a, x) { a[x.name] = x.value; return a; }, {});

Это похоже на ответ с помощью Array.prototype.map, но вам не нужно загромождать вашу область с помощью дополнительной переменной объекта. Одноразовые покупки.

ВАЖНОЕ ПРИМЕЧАНИЕ. Формы со вставками, которые имеют повторяющиеся атрибуты name, являются допустимыми HTML и на самом деле являются общим подходом. Использование любого из ответов в этом потоке будет неуместным в этом случае (поскольку объектные ключи должны быть уникальными).

50
ответ дан Ethan Brown 12 марта '15 в 4:23
источник поделиться

Все эти ответы казались мне слишком верными. Что-то нужно сказать для простоты. Пока все ваши входы формы имеют атрибут атрибута имени, это должно работать только джим-денди.

$('form.myform').submit(function () {
  var $this = $(this)
    , viewArr = $this.serializeArray()
    , view = {};

  for (var i in viewArr) {
    view[viewArr[i].name] = viewArr[i].value;
  }

  //Do stuff with view object here (e.g. JSON.stringify?)
});
28
ответ дан Jeffrey Van Alstine 01 апр. '11 в 0:45
источник поделиться

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

_.object(_.map($('#myform').serializeArray(), _.values))
24
ответ дан olleicua 12 нояб. '13 в 23:08
источник поделиться

Невозможно сделать это без изучения каждого из элементов. То, что вы действительно хотите знать, "кто-то еще уже написал метод, который преобразует форму в объект 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;
}
21
ответ дан tvanfosson 26 июля '09 в 17:01
источник поделиться

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

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

Вначале мы использовали метод jQuery serializeArray(), но это не включает в себя элементы формы, которые отключены. Мы часто будем отключать элементы формы, которые "синхронизируются" с другими источниками на странице, но нам все равно нужно включать данные в наш сериализованный объект. Итак, 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.

17
ответ дан Samuel Meacham 19 июля '10 в 2:57
источник поделиться

Эта функция должна обрабатывать многомерные массивы вместе с несколькими элементами с тем же именем.

Я использую его уже пару лет:

jQuery.fn.serializeJSON=function() {
  var json = {};
  jQuery.map(jQuery(this).serializeArray(), function(n, i) {
    var _ = n.name.indexOf('[');
    if (_ > -1) {
      var o = json;
      _name = n.name.replace(/\]/gi, '').split('[');
      for (var i=0, len=_name.length; i<len; i++) {
        if (i == len-1) {
          if (o[_name[i]]) {
            if (typeof o[_name[i]] == 'string') {
              o[_name[i]] = [o[_name[i]]];
            }
            o[_name[i]].push(n.value);
          }
          else o[_name[i]] = n.value || '';
        }
        else o = o[_name[i]] = o[_name[i]] || {};
      }
    }
    else {
      if (json[n.name] !== undefined) {
        if (!json[n.name].push) {
          json[n.name] = [json[n.name]];
        }
        json[n.name].push(n.value || '');
      }
      else json[n.name] = n.value || '';      
    }
  });
  return json;
};
16
ответ дан Sergey Varlamov 11 сент. '12 в 16:17
источник поделиться

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

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

См. JSON.

14
ответ дан Harini Sekar 07 апр. '14 в 13:40
источник поделиться

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

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"}
12
ответ дан Adrian Seeley 06 окт. '13 в 18:16
источник поделиться

Однострочный (без зависимостей, кроме 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" }

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

11
ответ дан test30 16 окт. '17 в 14:35
источник поделиться

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

Если введите имя как массив, например 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>
11
ответ дан Bhavik Hirani 31 авг. '16 в 14:35
источник поделиться

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

var values = $(this).serialize(),
attributes = {};

values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
    attributes[name] = value;
});
7
ответ дан ngr 06 апр. '13 в 23:43
источник поделиться

Используя решение 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" />
6
ответ дан G-Ram 11 окт. '13 в 17:04
источник поделиться

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

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

$.fn.serializeObject = function()
{
	return $.deparam(this.serialize());
};
5
ответ дан Roey 08 дек. '15 в 12:50
источник поделиться

От некоторого более старого ответа:

$('form input,select').toArray().reduce(function(m,e){m[e.name] = $(e).val(); return m;},{})
5
ответ дан juanpastas 14 июня '15 в 0:31
источник поделиться

Я нашел проблему с кодом Тобиаса Коэна (у меня недостаточно очков, чтобы прокомментировать это напрямую), что в противном случае работает для меня. Если у вас есть два варианта выбора с тем же именем, оба со значением = ", исходный код будет генерировать" имя ":" "вместо" 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;
};
4
ответ дан user1134789 03 марта '11 в 16:00
источник поделиться

Существует плагин для JQuery, jquery.serializeJSON. Я успешно использовал его в нескольких проектах. Отлично работает.

4
ответ дан Michael Yagudaev 03 янв. '14 в 3:24
источник поделиться

Если вы пытаетесь преобразовать все поля формы в JSON, чтобы отправить эту форму через Ajax, здесь плагин формы jQuery, который делает что.

4
ответ дан serg 26 июля '09 в 20:01
источник поделиться

Повернуть что-нибудь в объект (не тестировалось)

<script type="text/javascript">
string = {};

string.repeat = function(string, count)
{
    return new Array(count+1).join(string);
}

string.count = function(string)
{
    var count = 0;

    for (var i=1; i<arguments.length; i++)
    {
        var results = string.match(new RegExp(arguments[i], 'g'));
        count += results ? results.length : 0;
    }

    return count;
}

array = {};

array.merge = function(arr1, arr2)
{
    for (var i in arr2)
    {
        if (arr1[i] && typeof arr1[i] == 'object' && typeof arr2[i] == 'object')
            arr1[i] = array.merge(arr1[i], arr2[i]);
        else
            arr1[i] = arr2[i]
    }

    return arr1;
}

array.print = function(obj)
{
    var arr = [];
    $.each(obj, function(key, val) {
        var next = key + ": ";
        next += $.isPlainObject(val) ? array.print(val) : val;
        arr.push( next );
      });

    return "{ " +  arr.join(", ") + " }";
}

node = {};

node.objectify = function(node, params)
{
    if (!params)
        params = {};

    if (!params.selector)
        params.selector = "*";

    if (!params.key)
        params.key = "name";

    if (!params.value)
        params.value = "value";

    var o = {};
    var indexes = {};

    $(node).find(params.selector+"["+params.key+"]").each(function()
    {
        var name = $(this).attr(params.key),
            value = $(this).attr(params.value);

        var obj = $.parseJSON("{"+name.replace(/([^\[]*)/, function()
        {
            return '"'+arguments[1]+'"';
        }).replace(/\[(.*?)\]/gi, function()
        {
            if (arguments[1].length == 0)
            {
                var index = arguments[3].substring(0, arguments[2]);
                indexes[index] = indexes[index] !== undefined ? indexes[index]+1 : 0;

                return ':{"'+indexes[index]+'"';
            }
            else
                return ':{"'+escape(arguments[1])+'"';
        })+':"'+value.replace(/[\\"]/gi, function()
        {
            return "\\"+arguments[0]; 
        })+'"'+string.repeat('}', string.count(name, ']'))+"}");

        o = array.merge(o, obj);
    });

    return o;
}
</script>

Выход теста:

$(document).ready(function()
{
    console.log(array.print(node.objectify($("form"), {})));
    console.log(array.print(node.objectify($("form"), {selector: "select"})));
});

о

<form>
    <input name='input[a]' type='text' value='text'/>
    <select name='input[b]'>
        <option>select</option>
    </select>

    <input name='otherinput[c][a]' value='a'/>
    <input name='otherinput[c][]' value='b'/>
    <input name='otherinput[d][b]' value='c'/>
    <input name='otherinput[c][]' value='d'/>

    <input type='hidden' name='anotherinput' value='hidden'/>
    <input type='hidden' name='anotherinput' value='1'/>

    <input type='submit' value='submit'/>
</form>

даст:

{ input: { a: text, b: select }, otherinput: { c: { a: a, 0: b, 1: d }, d: { b: c } }, anotherinput: 1 }
{ input: { b: select } }
3
ответ дан eithed 23 февр. '12 в 19:59
источник поделиться

У меня была такая же проблема в последнее время и вышла с этот .toJSON jQuery плагин, который преобразует форму в объект 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-like database
  • Прочитайте его со своей серверной стороны $_POST [] и извлеките правильно вложенный массив, который вы можете затем семантически манипулировать
  • Используйте некоторую серверную script, чтобы преобразовать ее в хорошо сформированный XML файл (даже если вы не знаете его точной структуры a-priori)
  • Просто как-то используйте его, как в любом Node.js-like server script

ОК, так что теперь нам нужно подумать, как форма может представлять 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 здесь, который кто-то помог оптимизировать этот код Просмотрите нить и выглядите так:

$.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 стоит попробовать, а также тот факт, что вы можете добавлять теги ввода с одним и тем же именем, не беспокоясь, очень полезно, если вам нужно извлекать динамически созданные данные форм.

Надеюсь, это поможет кому-то!

3
ответ дан Onheiron 13 нояб. '12 в 21:18
источник поделиться

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

3
ответ дан Șerban Ghiță 03 окт. '13 в 16:55
источник поделиться

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

$.formObject = function($o) {
    var o = {},
        real_value = function($field) {
            var val = $field.val() || "";

            // additional cleaning here, if needed

            return val;
        };

    if (typeof o != "object") {
        $o = $(o);
    }

    $(":input[name]", $o).each(function(i, field) {
        var $field = $(field),
            name = $field.attr("name"),
            value = real_value($field);

        if (o[name]) {
            if (!$.isArray(o[name])) {
                o[name] = [o[name]];
            }

            o[name].push(value);
        }

        else {
            o[name] = value;
        }
    });

    return o;
}

Используйте так:

var obj = $.formObject($("#someForm"));

Проверено только в Firefox.

3
ответ дан kflorence 19 июня '10 в 1:47
источник поделиться

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

При использовании форм с именами на основе массива функция 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 и т.д.

3
ответ дан Sammaye 20 июня '11 в 12:46
источник поделиться

Другой ответ

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

2
ответ дан test30 20 окт. '17 в 19:08
источник поделиться

Мне нравится версия samuels, но я считаю, что у нее небольшая ошибка. Обычно 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;
}

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

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

2
ответ дан Frank Nocke 05 апр. '11 в 16:45
источник поделиться

Для быстрого, современного решения используйте плагин JSONify jQuery. Пример ниже приведен дословно из GitHub README. Весь кредит Кушалу Пандии, автору плагина.

Дано:

<form id="myform">
    <label>Name:</label>
    <input type="text" name="name"/>
    <label>Email</label>
    <input type="text" name="email"/>
    <label>Password</label>
    <input type="password" name="password"/>
</form>

Продолжительность:

$('#myform').jsonify();

Выдает:

{"name":"Joe User","email":"joe@example.com","password":"mypass"}

Если вы хотите сделать POST JQuery с этим объектом JSON:

$('#mybutton').click(function() {
    $.post('/api/user', JSON.stringify($('#myform').jsonify()));
}
2
ответ дан Jim Stewart 06 сент. '13 в 21:38
источник поделиться

используя lodash # set

let serialized = [
  { key: 'data[model][id]', value: 1 },
  { key: 'data[model][name]', value: 'product' },
  { key: 'sid', value: 'dh0un1hr4d' }
];

serialized.reduce(function(res, item) {
  _.set(res, item.key, item.value);
  return res;
}, {});

// returns
{
  "data": {
    "model": {
      "id": 1,
      "name": "product"
    }
  },
  "sid": "dh0un1hr4d"
}
1
ответ дан Ivan Nosov 10 июня '16 в 12:03
источник поделиться
  • 1
  • 2

Другие вопросы по меткам