javascript - 在 Laravel 中发布到数组错误

标签 javascript php laravel laravel-5

我有一个模型的编辑表单,其中有一个部分专门用于该特定记录的子记录,称为“shipment_details”。

编辑记录将始终显示至少一个现有的 shipment_detail 记录。目前我的“shipment_details”的 HTML 是来自 Blade 的:

<tbody>
    @foreach($shipment_details as $sd)
    <tr style="height:40px">
        <td style="width:8%;text-align:center;">{{Form::text('shipment_details['.$sd->id.'][piecesNumber]', $sd->pieces_number, array('class' => 'form-control','placeholder'=>'No. Pieces','required','id'=>'piecesNumber'))}}
        </td>
        <td style="width:16%;text-align:center;">
            {!! Form::select('shipment_details['.$sd->id.'][piecesType]', $piecetypes, $sd->pieces_type, ['id' => 'pieces_type', 'class' => 'form-control full-width','required']) !!}    
        </td>
        <td>
            {!! Form::select('shipment_details['.$sd->id.'][rateType]', $ratetypes, $sd->rate_type, ['id' => 'rateType', 'class' => 'form-control full-width','required']) !!}
        </td>
        <td style="width:16.5%;text-align:center;">
            {{Form::text('shipment_details['.$sd->id.'][weight]', $sd->weight, array('class' => 'form-control','placeholder'=>'Weight','required','id'=>'weight'))}}    
        </td>
        <td style="width:16.5%;text-align:center;">
            {{Form::select('shipment_details['.$sd->id.'][hazmat]',array(
                                    '0'=>'No',
                                    '1'=>'Yes',
                                ), $sd->hazmat, array('class' => 'form-control','id'=>'hazmat'))}}   
        </td>
        <td style="width:16.5%;text-align:center;">
                            {{Form::text('shipment_details['.$sd->id.'][description]', $sd->description, array('class' => 'form-control','placeholder'=>'Description','required','id'=>'description'))}} 
        </td>
        <td style="width:16.5%;text-align:center;">
            {{Form::text('shipment_details['.$sd->id.'][charge]', $sd->charge, array('class' => 'form-control','placeholder'=>'Charge','required','id'=>'charge'))}} 
        </td>
        <td><button type="button" name="add" id="add" class="btn btn-success">Add More</button></td>
    </tr>

    @endforeach
</tbody>

但是如果需要添加额外的 shipment_details,我有一个脚本可以添加格式如下的额外记录行:

<script>
 $(document).ready(function(){  
      var i=1;  
      $('#add').click(function(){  
            i++;  
           $('#freight_bill_items').append('<tr id="row'+i+'"> <td style="width:8%;text-align:center;">{{Form::text('shipment_details[piecesNumber][]', null, array('class' => 'form-control','placeholder'=>'No. Pieces','required','id'=>'piecesNumber'))}}</td><td style="width:16%;text-align:center;">{!! Form::select('shipment_details[piecesType][]', $piecetypes, 'null', ['id' => 'pieces_type', 'class' => 'form-control full-width','required']) !!} </td><td>{!! Form::select('shipment_details[rateType][]', $ratetypes, null, ['id' => 'rateType', 'class' => 'form-control full-width','required']) !!}</td><td style="width:16.5%;text-align:center;">{{Form::text('shipment_details[weight][]', null, array('class' => 'form-control','placeholder'=>'Weight','required','id'=>'weight'))}}</td><td style="width:16.5%;text-align:center;">{{Form::select('shipment_details[hazmat][]',array('No'=>'No','Yes'=>'Yes',), null, array('class' => 'form-control','id'=>'hazmat'))}}</td><td style="width:16.5%;text-align:center;">{{Form::text('shipment_details[description][]', null, array('class' => 'form-control','placeholder'=>'Description','required','id'=>'description'))}}</td><td style="width:16.5%;text-align:center;">{{Form::text('shipment_details[charge][]', null, array('class' => 'form-control','placeholder'=>'Charge','required','id'=>'charge'))}}</td><td><button type="button" name="remove" id="'+i+'" class="btn btn-danger btn_remove">X</button></td></tr>');   
      });  
      $(document).on('click', '.btn_remove', function(){  
           var button_id = $(this).attr("id");   
           $('#row'+button_id+'').remove();
           $( 'input[name^="shipment_details[charge][]"]' ).trigger( "change" );
      });

 });
</script>

当我去发布数据时,我的问题出现了,现有数据被正确“排列”,但新数据不是,此刻给我一个 undefined index 记录。

这是测试记录的 shipment_details 的当前 POST 数据输出:

装运详情

array:8 [▼
  13149 => array:7 [▼
    "piecesNumber" => "1"
    "piecesType" => "1"
    "rateType" => "1"
    "weight" => "12"
    "hazmat" => "0"
    "description" => "124"
    "charge" => "12.00"
  ]
  "piecesNumber" => array:1 [▼
    0 => "3"
  ]
  "piecesType" => array:1 [▼
    0 => "2"
  ]
  "rateType" => array:1 [▼
    0 => "2"
  ]
  "weight" => array:1 [▼
    0 => "1200"
  ]
  "hazmat" => array:1 [▼
    0 => "Yes"
  ]
  "description" => array:1 [▼
    0 => "desc2"
  ]
  "charge" => array:1 [▼
    0 => "40.00"
  ]
]

如您所见,除了现有记录外,输入都是独立的,所以我的问题一定出在我的表单上。有人有什么建议吗?

更新

使用上面的输出:

这是它应该如何发送(或以类似的格式):

  13149 => array:7 [▼
    "piecesNumber" => "1"
    "piecesType" => "1"
    "rateType" => "1"
    "weight" => "12"
    "hazmat" => "0"
    "description" => "124"
    "charge" => "12.00"
  ]

由于新记录尚未分配记录 ID,我认为新记录的顶行不会相同,但这应该可以解释我的请求。

更新

Controller 部分包含关于 shipment_detail 的部分

foreach ($request->shipment_details as $id => $details) {
            $shipdetail = Shipment_Detail::updateOrCreate(['id' => $id], [
            'pieces_type' => $details['piecesType'][0],
            'pieces_number' => $details['piecesNumber'][0],
            'rate_type' => $details['rateType'][0],
            'weight' => $details['weight'][0],
            'charge' => $details['charge'][0],
            'description' => $details['description'][0],
            'hazmat' => $details['hazmat'][0]
                ]);
        }

最佳答案

您的问题没有明显而简单的解决方案。

首先,您可以根据当前的 html 标记执行以下操作:

// Regroup post fields to required arrays' structure:

$new_items = [];
foreach ($request->shipment_details['piecesTtype'] as $key => $value) {
    $new_items[] = [
        'pieces_type' => $value,
        'pieces_number' => $request->shipment_details['piecesNumber'][$key],
        'rate_type' => $request->shipment_details['rateType'][$key],
        'weight' => $request->shipment_details['weight'][$key],
        'charge' => $request->shipment_details['charge'][$key],
        'description' => $request->shipment_details['description'][$key],
        'hazmat' => $request->shipment_details['hazmat'][$key],
    ];
}

// so, as these are new items - you can only create them.
// To distinguish existing items from new ones you can:

foreach ($request->shipment_details as $id => $details) {
    if (is_numeric($id)) {  // or any other function that checks if array key is a numeric value like 13149
        // update with $details
    }
}

另一种方法是您可以将 html 标记重写为如下内容:

<!-- I put only excerpt of fields -->
<input type="text" name="shipment_details[13149][piecesNumber]" value="" />

<!-- New fields will be added with an explicit indexing: -->
<input type="text" name="shipment_details[1][piecesNumber]" value="" />
<input type="text" name="shipment_details[2][piecesNumber]" value="" />
<input type="text" name="shipment_details[3][piecesNumber]" value="" />
<!-- and so on -->

在这种情况下,您将根据需要对项目进行分组,但实际情况是您将拥有索引 1、2、3 和更多 这将在您的循环中被视为 ids:

foreach ($request->shipment_details as $id => $details) {

    // as you have id = 1 for example, this record
    // will be updated if it exists, and as a result
    // wrong data will be in a database.
    $shipdetail = Shipment_Detail::updateOrCreate(['id' => $id], [
        ....
    ]);
}

同样在这种情况下,您需要修改您的 js 以计算某处的字段数并在 shipment_details[%INDEX%][piecesNumber] 中输出正确的索引。

第三种解决方案如下。您重建您的 html 布局,添加带有项目 ID 的特殊字段。

示例,同样只有部分字段:

<!-- Group 1, an existing record-->
<input type="hidden" name="shipment_details[itemId][]" value="13149" />
<input type="text" name="shipment_details[piecesNumber][]" value="Some existsing value" />
<input type="text" name="shipment_details[weight][]" value="Another existsing value" />

<!-- Group 2, new record-->
<input type="hidden" name="shipment_details[itemId][]" value="0" />
<input type="text" name="shipment_details[piecesNumber][]" value="Value will be input by user" />
<input type="text" name="shipment_details[weight][]" value="Value will be input by user" />

<!-- Group 3, new record-->
<input type="hidden" name="shipment_details[itemId][]" value="0" />
<input type="text" name="shipment_details[piecesNumber][]" value="Value will be input by user-2" />
<input type="text" name="shipment_details[weight][]" value="Value will be input by user-2" />

在这种情况下,您的数组结构将与您现在的结构相同,但不会有任何数字索引。 再次迭代它并创建所需的数组:

$new_items = $existsing_items = [];
foreach ($request->shipment_details['itemId'] as $key => $value) {
    if ($value != 0) {
        $existing_items[] = [
            'id' => $value,
            'pieces_number' => $request->shipment_details['piecesNumber'][$key],
            'rate_type' => $request->shipment_details['rateType'][$key],
            // other values
        ];
        // or update immediately
    } else {
        $new_items[] = [
            'pieces_type' => $value,
            'pieces_number' => $request->shipment_details['piecesNumber'][$key],
            'rate_type' => $request->shipment_details['rateType'][$key],
            // other values
        ];
        // or insert immediately
    }
}

但在这种情况下,一些坏人可以修改 shipment_details[itemId] 的值,而不是 0 values 会有真实的值,你将再次更新数据库中的错误数据。

所以,第一种方案还是最稳妥的。当然,有人可以改变 现有 id 字段的值,但我想您可以检查此类装运详细信息是否是当前用户的属性或任何其他条件。

也许您可以将字段名称拆分为现有字段和新字段,例如:

<!-- Group 1, an existing record-->
<input type="text" name="existsing_details[13149][piecesNumber]" value="Some existsing value" />
<input type="text" name="existsing_details[13149][weight]" value="Another existsing value" />

<!-- Group 2, another existing record-->
<input type="text" name="existsing_details[13150][piecesNumber]" value="Some existsing value" />
<input type="text" name="existsing_details[13150][weight]" value="Another existsing value" />

<!-- Group 3, new record-->
<input type="text" name="new_shipment_details[piecesNumber][]" value="Value will be input by user" />
<input type="text" name="new_shipment_details[weight][]" value="Value will be input by user" />

<!-- Group 4, new record-->
<input type="text" name="new_shipment_details[piecesNumber][]" value="Value will be input by user" />
<input type="text" name="new_shipment_details[weight][]" value="Value will be input by user" />

在这种情况下,您可以遍历 existing_details 并更新值,因为它们是现有值。 对于您使用上面的代码的新项目:

// Regroup post fields to required arrays' structure:

$new_items = [];
foreach ($request->new_shipment_details['piecesType'] as $key => $value) {
    $new_items[] = [
        'pieces_type' => $value,
        'pieces_number' => $request->new_shipment_details['piecesNumber'][$key],
        'rate_type' => $request->new_shipment_details['rateType'][$key],
        // other fields
    ];
    // or insert immediately
}

选择哪种方式由您决定。

关于javascript - 在 Laravel 中发布到数组错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48469244/

相关文章:

php - 使用 Laravel 5.4 和 Passport 的多重身份验证

javascript - 我需要一个电话号码的正则表达式,它不接受 0 作为 3 位美国区号的第一位数字

twitter-bootstrap - sass bootstrap 集成未显示字形图标

laravel - 丙酮包装Laravel 5.1安装

PHP 对 readdir 的权限被拒绝,即使它是相同的用户和组

javascript - 如何通过文本框数组提交按钮

php - Codeigniter join() 不起作用

javascript - 如何使用 jquery ajax 传递数据

javascript - 在其他事件发生后,复选框不会在页面上保持加载状态

javascript - Angularjs ng-禁用