Search code examples
phplaravellaravel-livewire

Update loop records via Laravel and livewire


Print

Hi, I would like some help on this.

This loop comes from my products table, using pure laravel I load each product in inputs, so if I make any changes and click on an update button it is redirected to a route to update the changed product.

How could I do this same idea using livewire?

How to display the updated data in this loop without having to go to another route.

My blade:

@forelse($categoryProduct->products as $key => $product)
<li>
    <div class="mt-3 card">
        <div class="card-body">
            <div class="row">
                <div class="col-1">
                    <x-inputs.group class="">
                        <div
                            x-data="imageViewer('{{ $product->img ? \Storage::url($product->img) : '' }}')">
                            <x-inputs.partials.label name="img" label="Foto">
                            </x-inputs.partials.label><br />

                            <!-- Show the image -->
                            <template x-if="imageUrl">
                                <img :src="imageUrl"
                                    class="object-cover border border-gray-200 rounded"
                                    style="width: 100px; height: 100px;" />
                            </template>

                            <!-- Show the gray box when image is not available -->
                            <template x-if="!imageUrl">
                                <div class="bg-gray-100 border border-gray-200 rounded"
                                    style="width: 140px; height: 140px;"></div>
                            </template>

                            <div class="mt-2">
                                <input wire:model="img" type="file" name="img" id="img"
                                    @change="fileChosen" />
                            </div>

                            @error('img')
                                @include('components.inputs.partials.error')
                            @enderror
                        </div>
                    </x-inputs.group>
                </div>
                <div class="col-11">
                    <div class="row">
                        <div class="col-10">
                            <input type="text" class="form-control" placeholder="Name"
                                value="{{ $product->name }}">
                        </div>
                        <div class="col-2">
                            <button
                                onclick="confirm('Tem certeza que deseja deletar esse produto?') || event.stopImmediatePropagation()"
                                wire:click.prevent="deleteProduct({{ $product->id }})"
                                class="btn btn-user btn-danger">
                                &times;
                            </button>
                        </div>
                        <div class="mt-3 col-10">
                            <textarea class="form-control"
                                placeholder="Description">{{ $product->description }}</textarea>
                        </div>
                        <div class="mt-3 col-2">
                            <input type="number" class="form-control"
                                placeholder="Price" value="{{ $product->price }}">
                        </div>
                    </div>
                </div>
            </div>
        </div>
</li>
@empty

This is the way I'm feeding the loop:

public function render()
    {
        $this->shop = Shop::with([
            'categoryProducts',
            'categoryProducts.products',
            'districts'
        ])->where('user_id', Auth::user()->id)->first();

        return view('app.menu-controller')
            ->extends('layouts.app')
            ->section('content');
    }

Solution

  • You can create a Livewire ProductComponent and in blade have the div card once this loop the same elements https://www.laravel-livewire.com/docs/2.x/making-components https://www.laravel-livewire.com/docs/2.x/rendering-components

    <div>
      <div class="mt-3 card">
            <div class="card-body">
                <div class="row">
                    <div class="col-1">
                        <x-inputs.group class="">
                            <div
                                x-data="imageViewer('{{ $product->img ? \Storage::url($product->img) : '' }}')">
                                <x-inputs.partials.label name="img" label="Foto">
                                </x-inputs.partials.label><br />
    
                 //......................               
      </div>
    </div>
    

    Use model binding in nested component for the loop https://www.laravel-livewire.com/docs/2.x/nesting-components

    @forelse($categoryProduct->products as $key => $product)
    <li>
       @livewire('product-component',['product' => $product], key($user->id))
    </li>
    

    and in component

    public Product $product;
    
    public function render()
    {
        return view('livewire.product-component')
                ->extends('layouts.app')
                ->section('content');
    }
    

    The rest in in Livewire documentation, when you get on there could come here with issues or questions. Greetings