【问题标题】:jquery serialize input with arraysjquery用数组序列化输入
【发布时间】:2012-06-23 01:01:06
【问题描述】:

我的网站上有这样的表格:

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

我想简单地抓取所有数据并将其发送到网络服务,所以有这个 js:

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

问题是,它使用输入名称中显示的所有括号创建 json,所以我得到一个解析错误。

如何使用 serializeArray 并获得正确的 json?

我希望看到的结果格式是这样的:

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

谢谢!

【问题讨论】:

  • 10 个问题,0% 接受答案。
  • 您必须更改输入的名称。 JSON 序列化程序不会为它们发明正确的名称。

标签: jquery json forms serialization multidimensional-array


【解决方案1】:

我做了一个递归函数/插件来做到这一点:

$.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>

除了整个 form 之外,您还可以在其他选择器上调用它。例如,调用:

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

将返回一个仅包含 name 字段的对象。有关更多示例,请参阅http://codepen.io/alexweissman/pen/MyWZdN

请注意(目前),这不适用于带空括号的字段名称(例如,input name="potatoes[]" 之类的字段将被忽略,因为无法提取唯一键)。

【讨论】:

  • 这是王牌。我尝试了 jquery-serialize-object 插件,该插件不起作用,但确实如此。可爱的。
  • 嗨,您的代码似乎没有正确序列化&lt;select multiple&gt;var val = this.value; 只返回第一个选定的值(在 Firefox 上测试)。由于这是 jquery 的一个 hack,我认为可以使用 $(this).val() 轻松修复。
  • 正是我想要的。感谢分享这个!绝对应该是公认的答案!
  • 二维数组失败
【解决方案2】:

这是一个版本的 alexw 代码,适用于带空括号的字段名称。这允许您管理具有多个值的字段(复选框、选择多个)。

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

【讨论】:

    【解决方案3】:

    鉴于您已成功将数组序列化为$fields,您现在可以遍历它并将其转换为更易于消化的结果对象:

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

    虽然$fields 是全局变量的有效名称,但我不能对这件事保持沉默:在 JavaScript 中,局部变量是用 var 关键字定义的,并且它们前面没有美元符号- 美元符号通常指 jQuery 对象。因此,您可以通过调用来获取字段:

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

    【讨论】:

    • 变量名无所谓,是否全局与问题无关。
    • 这只是我在输入问题时的一个错字。这是我的PHP出来了。
    • 当表单也有其他输入时,我怎样才能让它工作?当我添加诸如 之类的输入时,我收到一个 js 错误,即parts[1] 未定义。我认为这是因为它试图解析没有括号的元素。
    【解决方案4】:

    我使用serializeArray() 函数解决了我的问题

     let fd = $( "input[name^='INPUT_NAME']" ).serializeArray();
    

    【讨论】:

      【解决方案5】:

      serializeArray() 如果它写入输入数组。 但是它用名称'imputName []'保存它,问题是提取它。 但在这里我有一个解决方案。请检查代码语法。

      var formArraySerializado = $("#form").serializeArray();
      
      var imputArray = [];
      
      $(formArraySerializado).each(function(i, field){
          
          row[field.name] = field.value;
      
          if (field.name.indexOf("imputArray[]") >=0){
              imputArray.push(field.value)
          }
      });
      

      【讨论】:

        猜你喜欢
        • 2018-10-04
        • 1970-01-01
        • 1970-01-01
        • 2012-09-16
        • 1970-01-01
        • 1970-01-01
        • 2014-09-14
        • 2023-03-11
        • 2011-05-01
        相关资源
        最近更新 更多