【问题标题】:HTML Array Fields Parsing in PHPPHP 中的 HTML 数组字段解析
【发布时间】:2016-11-16 07:43:50
【问题描述】:

我有这样的表单设置:

<form action="/clients/{{ $client->id }}/create-invoice" method="post">
    <div class="form-group">
        <label for="due_date" class="sr-only">Due Date</label>
        <input type="date" name="due_date" class="form-control" placeholder="Due Date">
    </div>
    <hr />
    <p class="clearfix">
        <strong class="pull-left">Invoice Items</strong>
        <a id="add_invoice_item" class="pull-right"><span class="fa fa-plus"></span></a>
    </p>
    <div class="form-group invoice_item">
        <div class="row">
            <div class="col-ms-6 col-sm-8">
                <input type="text" name="item_description[]" class="form-control" placeholder="Description">
            </div>
            <div class="col-ms-3 col-sm-2">
                <input type="number" class="form-control" name="item_quantity[]" placeholder="Quantity">
            </div>
            <div class="col-ms-3 col-sm-2">
                <input type="text" class="form-control" name="item_price[]" placeholder="Price">
            </div>
        </div>
    </div>
    <div class="form-group">
        <input type="hidden" name="_token" value={{ csrf_token() }}>
        <button class="btn-primary btn btn-block">Create Invoice</button>
    </div>
</form>

我正在使用 Laravel 5.2。

我有以下 jQuery 允许用户添加更多发票项目:

$("#add_invoice_item").click(function(){
    $(".invoice_item").first().clone().insertAfter("div.invoice_item:last").find("input[type='text']").val("");
});

问题是当我查看请求时:

public function store(Request $request, Client $client)
{
    return $request->all();
}

它返回这个:

{
  "due_date": "2016-11-19",
  "item_description": [
    "Website Development",
    "SEO",
    "Server Setup"
  ],
  "item_quantity": [
    "1",
    "1",
    "1"
  ],
  "item_price": [
    "450.00",
    "300.00",
    "100.00"
  ],
  "_token": "7tUMdXX9FBU4a7cug51oBlrRyeBi9H8ucUNltQgM"
}

虽然这是预期的结果,但我不确定如何让它以易于使用的方式返回。

例如,我需要一个数组列表,而不是 3 个不同的数组列表,我需要一个数组列表,其中每个对象具有该行对象的每个字段。

所以:

它会返回这个:

{
  "due_date": "2016-11-19",
  "items": [
    {"description": "Server Setup", "price": "100.00", "quantity": "1"},
    {"description": "SEO", "price": "300.00", "quantity": "1"},
    {"description": "Website Development", "price": "450.00", "quantity": "1"}
  ],
  "_token": "7tUMdXX9FBU4a7cug51oBlrRyeBi9H8ucUNltQgM"
}

我假设我需要更改 HTML 和 jQuery,但我不确定如何使其正常工作,以便 jQuery 将新字段正确添加到 items 的数组中

谢谢!

【问题讨论】:

  • 我建议您保留请求数据的原样。因为循环遍历任一数组并使用当前迭代的索引来匹配所有数组中的项目比在提交之前破解表单的内容要简单得多。
  • in html 用唯一的 id 对复选框进行分组,无论是数据库中的 id 还是您仅在 html 页面上使用的 id,例如:&lt;input type="checkbox" name="item_price[0]"&gt; &lt;input type="checkbox" name="item_description[0]"&gt; etc

标签: javascript php jquery arrays laravel


【解决方案1】:

将数组的命名更改为product[i][field]

<input type="text" name="product[0][description]"/>
<input type="text" name="product[0][quantity]"/>
<input type="text" name="product[0][price]"/>

<input type="text" name="product[1][description]"/>
<input type="text" name="product[1][quantity]"/>
<input type="text" name="product[1][price]"/>

在 PHP 中你会收到这个:

var_dump($_POST['product']);

[
    [
        'description': 'Website development',
        'quantity': '1',
        'price': '450.00'
    ],
    [
        'description': 'SEO',
        'quantity': '1',
        'price': '300.00'
    ],
]

唯一的缺点是需要手动设置数组索引。


使用 jQuery 和模板:

var index = 0;

function add() {
  $('.form').append(template('#my-template', {
    i: index
  }));
  index++;
}

function template(selector, params) {
  if (typeof params === 'undefined') {
    params = [];
  }

  var tplEl = $(selector);

  if (tplEl.length) {
    var tpl = $(selector).html();

    $.each(params, function(i, n) {
      tpl = tpl.replace(new RegExp("\\{" + i + "\\}", "g"), function() {
        if (typeof n === 'object') {
          return n.get(0).outerHTML;
        } else {
          return n;
        }
      });
    });

    return $(tpl);
  } else {
    console.error('Template "' + selector + '" not found!');
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onClick="add()">Add more</button>
<hr/>
<div class="form">

</div>
<script type="text/jQuery-tpl" id="my-template">
  <div class="row">
    {i}: 
    <input type="text" name="product[{i}][description]" />
    <input type="text" name="product[{i}][quantity]" />
    <input type="text" name="product[{i}][price]" />
  </div>
</script>

【讨论】:

  • 是的,我无法设置数组索引(正如我在问题中所说,它需要使用 jQuery 完成)。
  • @Shiv 其实你可以。我已经做过几次了。无需克隆您的输入,只需使用一些模板 HTML,您可以在其中传入索引 var newInput = $('&lt;input&gt;', {name: 'product['+i+'][description]'});。另外我认为在克隆您的项目时,输入的值也会被克隆(可能是不利的)
  • @Shiv 为了什么?
  • jquery 中的模板
【解决方案2】:

啊,它必须在 jQuery 中完成。嗯,这也很容易。做这样的事情:

$('.invoice_item').each(function(i, el) {
    // i holds the index. Use it to alter the checkboxes
    $(this)
        .find('input[name="item_description[]"]')
        .attr('name', 'item_description[' + i + ']');

    // Do the same for price and quantity
});

当您发布表单时,项目属性将按每一行分组。

【讨论】:

  • 如果可以直接设置格式化名称,为什么还要使用两个函数?
  • 因为这正好符合他的目的。如果 OP 想不到这一点,那么使用解析字段名称的正则表达式和函数就大材小用了。
  • 啊顺便说一句,我没有看到他用 jquery 添加更多发票项目行的部分,我太快了。反正;是的,在这种情况下,在该函数中添加索引更合理
猜你喜欢
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 2011-04-05
  • 2014-04-02
  • 1970-01-01
相关资源
最近更新 更多