编辑表单刀片 Laravel 中的嵌套循环

Posted

技术标签:

【中文标题】编辑表单刀片 Laravel 中的嵌套循环【英文标题】:Nested Loop in Edit Form Blade Laravel 【发布时间】:2022-01-23 20:23:14 【问题描述】:

我有一个使用行跨度表和嵌套循环的编辑表单。我还有一个创建数据表单,可以像这样正常工作。我在这个项目中使用了 Laravel 8。

Create form

但是当我从数据库中添加值来创建编辑表单时:

Edit form -1 Edit Form -2

我从数据库中获取 sasaran、indikator 和数据(问题),然后使用嵌套循环对其进行循环。仅供参考,我有 3 个 sasaran 的数据、12 个指标的数据和 47 个问题数据,需要与行跨一起加载。但是当我创建编辑表单时,行跨度不适合 sasaran、indikator 或问题数量,但它循环了 47 次。行跨度仅适用于 saran 的每个第一个数据,然后不适用于其余部分(如 Edit Form -1)并且还会复制数据。

仅供参考,我没有使用 Ajax 来创建和编辑表单。

这是代码:

查看:

@foreach($sasarans as $i => $sasaran)
@foreach($sasaran->indikator as $indikator)
@foreach($data_laporans as $data)
<tr>
    @if($loop->first)
    <td style="text-align:center; vertical-align:middle;"
        rowspan="$indikator->pertanyaan->count()">
        $i+1 </td>
    <td style="vertical-align:middle;"
        rowspan="$indikator->pertanyaan->count()">
        $sasaran->sasaran </td>
    <td style="vertical-align:middle;"
        rowspan="$indikator->pertanyaan->count()">
         $indikator->indikator </td>
    @endif
    <td style="vertical-align:middle;">
        <textarea style="height:130px;"
            class="form-control transparent disable"
            readonly> $data->pertanyaan->pertanyaan</textarea>
        <input type="hidden" name="id_pertanyaan[]" class="form-control"
            value="$data->id_pertanyaan">
    </td>
    <td>
        <input type="text" name="jumlah[]"
            class="form-control @error('jumlah') is-invalid @enderror"
            value="$data->jumlah">

        <!--Error Message-->
        @error('jumlah')
        <span class="invalid-feedback" role="alert">
            <strong> $message </strong>
        </span>
        @enderror
    </td>
    <td>
        <textarea name="keterangan[]"
            class="form-control @error('keterangan') is-invalid @enderror" value="$data->keterangan"></textarea>

        <!--Error Message-->
        @error('keterangan')
        <span class="invalid-feedback" role="alert">
            <strong> $message </strong>
        </span>
        @enderror
    </td>
    <td>
        <div class="custom-file"
            style="margin-left:10px; margin-right:10px;">
            <input type="file" name="bukti[]" class="custom-file-input">
            <label class="custom-file-label"></label>
        </div>

        <!--Error Message-->
        @error('bukti')
        <span class="invalid-feedback" role="alert">
            <strong> $message </strong>
        </span>
        @enderror

    </td>
</tr>
@endforeach
@endforeach
@endforeach

控制器:

public function edit($id)

    $sasarans = Sasaran::all();
    $laporan_indikators = LaporanIndikator::where('id',$id)->first();
    $data_laporans = DataLaporan::where('id_laporan',$id)->get();
    return view('indikator-kinerja.edit',compact('laporan_indikators','data_laporans','sasarans'));

Sasaran 模型:

protected $fillable = ['sasaran'];

public function indikator() 
    return $this->hasMany(DataIndikator::class, 'id_sasaran','id');

Indikator 型号:

protected $fillable = ['id_sasaran', 'indikator'];

public function sasaran() 
    return $this->belongsTo(Sasaran::class, 'id_sasaran','id');


public function pertanyaan() 
    return $this->hasMany(Pertanyaan::class, 'id_indikator','id');

Pertanyaan 的模型:

protected $fillable = ['id_indikator', 'pertanyaan'];

public function indikator() 
    return $this->belongsTo(DataIndikator::class, 'id_indikator','id');


public function data_laporan() 
    return $this->belongsTo(DataLaporan::class, 'id_laporan','id');

Data Laporan 的模型:

protected $fillable = ['id_laporan', 'id_pertanyaan','jumlah','keterangan','bukti'];

public function laporan() 
    return $this->belongsTo(LaporanIndikator::class, 'id_laporan','id');


public function pertanyaan() 
    return $this->belongsTo(Pertanyaan::class, 'id_pertanyaan','id');

Laporan Indikator 的模型:

 public function data_laporan() 
    return $this->hasMany(DataLaporan::class);

我真的很抱歉我的英语不好,但我真的很感谢你的帮助。谢谢。

更新:在我看来,我试图这样做以修复行跨度,但问题是每个 sararan 和 indikator 循环 47 次(我的意思是,不适合它的 sasaran 和 indikator 的数量),以及indikator 不适合 sasaran。您可以查看我为我想要的示例视图附加的创建表单视图。我想我知道问题出在哪里,但我真的不知道如何解决它。请帮助我,因为我仍然是初学者。谢谢。

新视图的代码:

@foreach($sasarans as $i => $sasaran)
 @php ($first = true) @endphp
   @foreach($sasaran->indikator as $indikator)
     @foreach($data_laporans as $data)
       <tr>
       @if($loop->first)
         <td rowspan="$data->pertanyaan->count()">$i+1 </td>
         <td rowspan="$data->pertanyaan->count()">$sasaran->sasaran</td>
         <td rowspan="$data->pertanyaan->count()">$indikator->indikator </td>
 @php ($first = false) @endphp
       @endif
       <td style="vertical-align:middle;"><textarea style="height:130px;"
                                                         class="form-control transparent disable" readonly> $data->pertanyaan->pertanyaan</textarea>
<input type="hidden" name="id_pertanyaan[]" class="form-control" value="$data->pertanyaan->id"></td>
      <td><input type="text" name="jumlah[]" class="form-control @error('jumlah') is-invalid @enderror" value="$data->jumlah">
          <!--Error Message-->
          @error('jumlah')
           <span class="invalid-feedback" role="alert">
             <strong> $message </strong>
            </span>
           @enderror
     </td>
     <td><textarea name="keterangan[]" class="form-control @error('keterangan') is-invalid @enderror">$data->keterangan</textarea> 
          <!--Error Message-->
          @error('keterangan')
            <span class="invalid-feedback" role="alert">
              <strong> $message </strong>
             </span>
            @enderror
    </td>
    <td>
      <div class="custom-file" style="margin-left:10px; margin-right:10px;">
        <input type="file" name="bukti[]" class="custom-file-input"> 
        <label class="custom-file-label"></label>
       </div>
     <!--Error Message-->
     @error('bukti')
      <span class="invalid-feedback" role="alert">
       <strong> $message </strong>
      </span>
     @enderror
   </td>
  </tr>
 @endforeach
@endforeach
@endforeach

New View -1New View - 2

【问题讨论】:

请花时间格式化您的问题代码。行上不需要 50 个前导空格! 【参考方案1】:

更新: 您需要做的只是在 data 循环中循环特定数量的索引。

@php $last_count = 0; @endphp
@foreach($sasarans as $i => $sasaran)
    @foreach($sasaran->indikator as $indikator)
        @foreach(array_slice($data_laporans->toArray(), $last_count, $data_count) as $data)
            @php
                $data_count = $data->pertanyaan->count();
            @endphp
            <tr>
                @if($loop->parent->parent->first)
                    <td rowspan="$data_count">$i+1 </td>
                    <td rowspan="$data_count">$sasaran->sasaran</td>
                    <td rowspan="$data_count">$indikator->indikator </td>
                @endif                
                <td style="vertical-align:middle;">
                    <textarea style="height:130px;" class="form-control transparent disable" readonly> $data->pertanyaan->pertanyaan</textarea>
                    <input type="hidden" name="id_pertanyaan[]" class="form-control" value="$data->pertanyaan->id">
                </td>
                <td>
                    <input type="text" name="jumlah[]" class="form-control @error('jumlah') is-invalid @enderror" value="$data->jumlah">
                    <!--Error Message-->
                    @error('jumlah')
                        <span class="invalid-feedback" role="alert">
                            <strong> $message </strong>
                        </span>
                    @enderror
                 </td>
                 <td>
                     <textarea name="keterangan[]" class="form-control @error('keterangan') is-invalid @enderror">$data->keterangan</textarea> 
                     <!--Error Message-->
                     @error('keterangan')
                         <span class="invalid-feedback" role="alert">
                             <strong> $message </strong>
                          </span>
                     @enderror
                  </td>
                  <td>
                      <div class="custom-file" style="margin-left:10px; margin-right:10px;">
                          <input type="file" name="bukti[]" class="custom-file-input"> 
                          <label class="custom-file-label"></label>
                      </div>
                      <!--Error Message-->
                      @error('bukti')
                          <span class="invalid-feedback" role="alert">
                              <strong> $message </strong>
                           </span>
                      @enderror
                  </td>
              </tr>
         @endforeach
         @php $last_count += $data_count; @endphp
    @endforeach
@endforeach

尝试一下,看看它是否有效。很遗憾,我自己无法调试。

旧答案: $loop-&gt;first 仅在第一次有效,因此您的 sasaran 在第一次之后中断。

将开头替换为:

@php
    $tracker = -1;
@endphp
@foreach($sasarans as $i => $sasaran)
    @foreach($sasaran->indikator as $indikator)
        @foreach($data_laporans as $data)
            <tr>
                @php
                    if($tracker !== $i)
                    
                        $tracker = $i;
                        $new_row = true;
                     else 
                        $new_row = false;
                    
                @endphp
                @if($new_row)
                    <td style="text-align:center; vertical-align:middle;" rowspan="$indikator->pertanyaan->count()">$i+1 </td>
                    <td style="vertical-align:middle;" rowspan="$indikator->pertanyaan->count()">$sasaran->sasaran </td>
                    <td style="vertical-align:middle;" rowspan="$indikator->pertanyaan->count()"> $indikator->indikator </td>
                @endif

                // Your remaining code

试试这个,看看它是否解决了sasaran 只能在第一次工作的问题?

【讨论】:

输出如下:imgur.com/a/D83Y4yz。我只是在 endif 之前添加带有前 3 个 的 @else。你有什么建议可以不用 $loop->first 吗? 我已经用一些标记编辑了答案,请检查这是否是你所做的。我会尝试在我的本地格式化您的代码,也许我可以弄清楚。如果我弄明白了,会更新答案。 我想我有解决sasaran 仅在第一次工作的问题的解决方案,请检查。 我已经尝试过您的解决方案,但结果仍然与我在问题中附加的编辑表单图像相同。这是链接:imgur.com/a/nUDFAfp。先生,您能帮帮我吗?谢谢 是的,我发布的内容只会在最初加载数据以正确显示所有 sasaran 集时对您有所帮助(对于您的问题:rowspan 仅适用于萨萨兰)。仍然无法在编辑页面上使用。编辑的问题是您正在添加一个新行,但没有更改与之关联的sasaranrowspan。您必须编写一些 JS 或其他内容来增加 sasaranrowspan,这可能会解决您面临的问题。 【参考方案2】:

尝试了几次,终于找到了解决办法。我只是像这样添加变量 $data_laporans:

@foreach($sasarans as $i => $sasaran)
   @php ($first = true) @endphp
   @foreach($sasaran->indikator as $indikator)
     @foreach($indikator->pertanyaan as $pertanyaan)
        <tr>
           @if($loop->first)
              <td rowspan="$indikator->pertanyaan->count()">$i+1 </td>
              <td rowspan="$indikator->pertanyaan->count()">$sasaran->sasaran</td>
               <td rowspan="$indikator->pertanyaan->count()">$indikator->indikator</td>
             @php ($first = false) @endphp
             @endif
                <td><textarea> $pertanyaan->pertanyaan</textarea></td>
                @foreach($pertanyaan->data_laporan as $data)
                <!--Add your data here-->
                @endforeach
  </tr>
  @endforeach
 @endforeach
@endforeach

我也改变了 DataLaporan 和 Pertanyaan 之间的关系:

DataLaporan 模型:

public function pertanyaan() 
    return $this->belongsTo(Pertanyaan::class, 'id_pertanyaan','id');

Pertanyaan 模型:

public function data_laporan() 
    return $this->hasMany(DataLaporan::class, 'id_pertanyaan','id');

【讨论】:

以上是关于编辑表单刀片 Laravel 中的嵌套循环的主要内容,如果未能解决你的问题,请参考以下文章

循环 PHP 嵌套数组 - 将值提取到刀片视图中 (Laravel)

刀片模板中的多对多关系中的 Laravel 嵌套查询

laravel 在循环中停止嵌套回复表单[关闭]

嵌套的 foreach 循环使用 if 条件创建重复记录 - PHP Laravel 8

循环遍历 Laravel Blade 模板中的嵌套数组

Laravel 5.8刀片,从嵌套对象错误中获取值