Laravel:在数据透视表中设置旧的选中复选框

huangapple go评论104阅读模式
英文:

Laravel: Set old checked checkbox with pivot tables

问题

我不知道如何检查与数据透视表的“旧”值。我正在构建电子商务平台,每个产品类别可以有多个商店。在创建新类别时,我只选择一个商店,然后提交后选择的商店取消选中。

我的尝试

<!-- 仅在更新时显示,一切正常 -->
@if(isset($category))
    @foreach($stores as $store)
        <div class="form-check">
            @if($category->stores()->pluck('store.id')->contains($store->id))
                <input type="checkbox" name="stores[]" checked value="{{ $store->id }}">
            @else
                <input type="checkbox" name="stores[]" value="{{ $store->id }}">
            @endif
            <label class="form-check-label" for="category_status_field">{{ $store->name }}</label>
        </div>
    @endforeach
@else
    <!-- 仅在创建时显示 -->
    @foreach($stores as $store)
        <div class="form-check">
            <!-- 这里出现问题 -->
            <input type="checkbox" name="stores[]" {{ old('stores') == $store->categories()->pluck('category.id')->contains($store->id) ? 'checked' : '' }} value="{{ $store->id }}">
            <label class="form-check-label" for="category_status_field">{{ $store->name }}</label>
        </div>
    @endforeach
@endif

模型

class Store extends Model
{
    public function categories()
    {
        return $this->belongsToMany(Category::class, 'category_store', 'store_id');
    }
}

class Category extends Model
{
    public function stores()
    {
        return $this->belongsToMany(Store::class, 'category_store', 'category_id');
    }
}

我还尝试过

<input type="checkbox" name="stores[]" {{ old('stores[$store->id]') == $store->id ? 'checked' : '' }} value="{{ $store->id }}">

我不明白如何检查哪个复选框已选中以及与什么匹配以显示“checked”。

谢谢。

英文:

I dont know how to check old value with pivot tables. Am building ecommerce platform and each product category can have many stores. During creation new category i select only one store and after submit sleceted store is unchecked.

What i try

    &lt;!-- Show only on update and all works good --&gt;
    
    @if(isset($category))
        @foreach($stores as $store)
            &lt;div class=&quot;form-check&quot;&gt;
                @if($category-&gt;stores()-&gt;pluck(&#39;store.id&#39;)-&gt;contains($store-&gt;id))
                    &lt;input type=&quot;checkbox&quot; name=&quot;stores[]&quot; checked value=&quot;{{ $store-&gt;id }}&quot;&gt;
                @else
                    &lt;input type=&quot;checkbox&quot; name=&quot;stores[]&quot;  value=&quot;{{ $store-&gt;id }}&quot;&gt;
                @endif
                &lt;label class=&quot;form-check-label&quot; for=&quot;category_status_field&quot;&gt;{{ $store-&gt;name }}&lt;/label&gt;
            &lt;/div&gt;
        @endforeach
    @else
    
        &lt;!-- Show only on create --&gt;
    
        @foreach($stores as $store)
            &lt;div class=&quot;form-check&quot;&gt;

               &lt;!-- Here is problem --&gt;

                &lt;input type=&quot;checkbox&quot; name=&quot;stores[]&quot; {{ old(&#39;stores&#39;) == $store-&gt;categories()-&gt;pluck(&#39;category.id&#39;)-&gt;contains($store-&gt;id) ? &#39;checked&#39; : &#39;&#39; }}  value=&quot;{{ $store-&gt;id }}&quot;&gt;
                &lt;label class=&quot;form-check-label&quot; for=&quot;category_status_field&quot;&gt;{{ $store-&gt;name }}&lt;/label&gt;
            &lt;/div&gt;
        @endforeach
    @endif
@endif

Models

class Store extends Model
{
    public function categories()
    {
        return $this-&gt;belongsToMany(Category::class, &#39;category_store&#39;, &#39;store_id&#39;);
    }
}

class Category extends Model
{
    public function stores()
    {
        return $this-&gt;belongsToMany(Store::class, &#39;category_store&#39;, &#39;category_id&#39;);
    }
}

I also try

&lt;input type=&quot;checkbox&quot; name=&quot;stores[]&quot; {{ old(&#39;stores[$store-&gt;id]&#39;) == $store-&gt;id ? &#39;checked&#39; : &#39;&#39; }}  value=&quot;{{ $store-&gt;id }}&quot;&gt;

I dont understand how to check what checkbox is checked and with what to match to show checked.

Thanks

答案1

得分: 2

你有一些问题,首先是一个N+1问题,你在foreach()循环的每次迭代中都加载了每个关联的store.id。让我们首先解决这个问题。

在渲染此视图的控制器中,定义以下内容:

public function edit($categoryId) {
  $category = Category::findOrFail($categoryId);
  
  return view('categories.edit', [
    'category' => $category,
    'stores' => Store::all(), // 或类似的
    'storeIds' => $category->stores->pluck('id')
  ]);
}

如果你正在使用Route Model Binding,你可以跳过上面的步骤,直接这样做:

public function edit(Category $category) { 
  return view('categories.edit', [
    'category' => $category,
    'stores' => Store::all(), // 或类似的
    'storeIds' => $category->stores->pluck('id')
  ]);
}

现在,你可以在视图中引用$storeIds。然后,你可以使用@checked属性(在Laravel 9.x中可用):

@foreach($stores as $store)
  <div class="form-check">
    <input type="checkbox" name="stores[]" @checked((old() ? collect(old('stores', []))->contains($store->id) : $storeIds->contains($store->id))) value="{{ $store->id }}">
    <label class="form-check-label" for="category_status_field">{{ $store->name }}</label>
  </div>
@endforeach

这将检查old()值(来自会话重定向)或者$storeIds是否包含每个$store->id,如果包含,将标记输入为checked

参考:

@checked 文档

英文:

You've got a couple issues, the first of which is an N+1 issue, where you're loading every associated store.id on every iteration of your foreach() loop. Let's fix that first.

In your Controller that renders this view, define the following:

public function edit($categoryId) {
  $category = Category::findOrFail($categoryId);
  
  return view(&#39;categories.edit&#39;, [
    &#39;category&#39; =&gt; $category,
    &#39;stores&#39; =&gt; Store::all(), // or similar
    &#39;storeIds&#39; =&gt; $category-&gt;stores-&gt;pluck(&#39;id&#39;)
  ]);
}

If you're using Route Model Binding, you can skip that and simply do:

public function edit(Category $category) { 
  return view(&#39;categories.edit&#39;, [
    &#39;category&#39; =&gt; $category,
    &#39;stores&#39; =&gt; Store::all(), // or similar
    &#39;storeIds&#39; =&gt; $category-&gt;stores-&gt;pluck(&#39;id&#39;)
  ]);
}

Now, you can reference $storeIds in your view. You can then use the @checked property (available in Laravel 9.x)

@foreach($stores as $store)
  &lt;div class=&quot;form-check&quot;&gt;
    &lt;input type=&quot;checkbox&quot; name=&quot;stores[]&quot; @checked((old() ? collect(old(&#39;stores&#39;, []))-&gt;contains($store-&gt;id) : $storeIds-&gt;contains($store-&gt;id))) value=&quot;{{ $store-&gt;id }}&quot;&gt;
    &lt;label class=&quot;form-check-label&quot; for=&quot;category_status_field&quot;&gt;{{ $store-&gt;name }}&lt;/label&gt;
  &lt;/div&gt;
@endforeach

This will check both the old() values (from session redirect), or $storeIds to see if it contains each $store-&gt;id, and if it does, will mark the input as `checked.

For reference:

@checked Documentation

答案2

得分: 1

问题已解决

<input type="checkbox" name="stores[]" {{ is_array(old('stores')) && in_array($store->id, old('stores')) ? 'checked ' : '' }}  value="{{ $store->id }}">
英文:

Problem sloved

&lt;input type=&quot;checkbox&quot; name=&quot;stores[]&quot; {{ is_array(old(&#39;stores&#39;)) &amp;&amp; in_array($store-&gt;id, old(&#39;stores&#39;))  ? &#39;checked &#39; : &#39;&#39; }}  value=&quot;{{ $store-&gt;id }}&quot;&gt;

huangapple
  • 本文由 发表于 2023年7月14日 05:33:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76683369.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定