最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Laravel livewire checkbox to select on multiple pages - Stack Overflow

programmeradmin1浏览0评论

I'm building a table with a select on each row, and a "Select All" Option, with Laravel and Livewire, currently, it works but, my records are paginated, say for example, page 1 shows records 1 through 6, and page 2, records from 7 through 12.

If I select on the first page, records 1 and 2, ( rows 1 and 2 ), and then go to page 2, the checkboxes for rows 1 and 2 are checked. How can I fix it so that, when I paginate, the rows whose records I haven't selected are not checked?

 <div class="table-container">
            <table class="table">
                <thead>
                <tr>
                    <th>
                        <input type="checkbox" class="sales-checkbox" wire:model.live="selectAll"/>
                    </th>
                    <th>Número</th>
                    <th>Cliente</th>
                    <th>Creación</th>
                    <th>Vencimiento</th>
                    <th>Total</th>
                    <th>Por Cobrar</th>
                    <th>Estado</th>
                    <th>Acciones</th>
                </tr>
                </thead>
                <tbody>
                @foreach($invoices as $invoice)
                    <tr>
                        <th class="whitespace-nowrap align-content-center align-items-center text-center">
                            @if($invoice->trashed())
                                -
                            @else
                            <input type="checkbox" class="sales-checkbox" wire:model.live="selected"
                                   @if(in_array($invoice->id, $selected)) checked @endif
                                   value="{{ $invoice->id }}"/>
                            @endif
                        </th>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->invoice_number }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->customer->name }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->created_at->format('d/m/Y') }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->expiration_date->format('d/m/Y') }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">C$ {{ \Illuminate\Support\Number::format($invoice->total_amount) }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">C$ {{ \Illuminate\Support\Number::format($invoice->total_amount - $invoice->payments->sum('amount_in_nio')) }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">
                           @if($invoice->trashed())
                                <x-jemg-components.invoice-status-badges
                                    type="danger"
                                    text="Anulada">
                                </x-jemg-components.invoice-status-badges>
                            @else
                                <x-jemg-components.invoice-status-badges
                                    type="{{ $invoice['status_labels']['type'] }}"
                                    text="{{ $invoice['status_labels']['label'] }}">
                                </x-jemg-components.invoice-status-badges>
                            @endif
                        </td>
                        <td class="whitespace-nowrap align-content-center align-items-center">
                            <x-jemg-components.flat-actions
                                :show="route('admin.sales.show',$invoice)"
                                :export="route('admin.sales.export',$invoice)"
                                :model="$invoice"
                                :trashed="$invoice->trashed()"
                            />
                        </td>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>

Component Class:

class SalesIndex extends Component
{

use WithPagination;

public $selected = [];
public $selectAll = false;

public function render()
{
    $invoices = Invoice::query()
        ->with(['customer', 'user', 'subProducts', 'payments'])
        ->latest('id')
        ->withTrashed()
        ->paginate(50);

    return view('livewire.sales.sales-index', compact('invoices'));
}

public function updatedSelectAll($value)
{
    if ($value) {
        $this->selected = Invoice::pluck('id')->map(fn ($id) => (string) $id)->toArray();
    } else {
        $this->selected = [];
    }
}
}

I'm building a table with a select on each row, and a "Select All" Option, with Laravel and Livewire, currently, it works but, my records are paginated, say for example, page 1 shows records 1 through 6, and page 2, records from 7 through 12.

If I select on the first page, records 1 and 2, ( rows 1 and 2 ), and then go to page 2, the checkboxes for rows 1 and 2 are checked. How can I fix it so that, when I paginate, the rows whose records I haven't selected are not checked?

 <div class="table-container">
            <table class="table">
                <thead>
                <tr>
                    <th>
                        <input type="checkbox" class="sales-checkbox" wire:model.live="selectAll"/>
                    </th>
                    <th>Número</th>
                    <th>Cliente</th>
                    <th>Creación</th>
                    <th>Vencimiento</th>
                    <th>Total</th>
                    <th>Por Cobrar</th>
                    <th>Estado</th>
                    <th>Acciones</th>
                </tr>
                </thead>
                <tbody>
                @foreach($invoices as $invoice)
                    <tr>
                        <th class="whitespace-nowrap align-content-center align-items-center text-center">
                            @if($invoice->trashed())
                                -
                            @else
                            <input type="checkbox" class="sales-checkbox" wire:model.live="selected"
                                   @if(in_array($invoice->id, $selected)) checked @endif
                                   value="{{ $invoice->id }}"/>
                            @endif
                        </th>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->invoice_number }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->customer->name }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->created_at->format('d/m/Y') }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">{{ $invoice->expiration_date->format('d/m/Y') }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">C$ {{ \Illuminate\Support\Number::format($invoice->total_amount) }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">C$ {{ \Illuminate\Support\Number::format($invoice->total_amount - $invoice->payments->sum('amount_in_nio')) }}</td>
                        <td class="whitespace-nowrap align-content-center align-items-center">
                           @if($invoice->trashed())
                                <x-jemg-components.invoice-status-badges
                                    type="danger"
                                    text="Anulada">
                                </x-jemg-components.invoice-status-badges>
                            @else
                                <x-jemg-components.invoice-status-badges
                                    type="{{ $invoice['status_labels']['type'] }}"
                                    text="{{ $invoice['status_labels']['label'] }}">
                                </x-jemg-components.invoice-status-badges>
                            @endif
                        </td>
                        <td class="whitespace-nowrap align-content-center align-items-center">
                            <x-jemg-components.flat-actions
                                :show="route('admin.sales.show',$invoice)"
                                :export="route('admin.sales.export',$invoice)"
                                :model="$invoice"
                                :trashed="$invoice->trashed()"
                            />
                        </td>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>

Component Class:

class SalesIndex extends Component
{

use WithPagination;

public $selected = [];
public $selectAll = false;

public function render()
{
    $invoices = Invoice::query()
        ->with(['customer', 'user', 'subProducts', 'payments'])
        ->latest('id')
        ->withTrashed()
        ->paginate(50);

    return view('livewire.sales.sales-index', compact('invoices'));
}

public function updatedSelectAll($value)
{
    if ($value) {
        $this->selected = Invoice::pluck('id')->map(fn ($id) => (string) $id)->toArray();
    } else {
        $this->selected = [];
    }
}
}
Share asked Mar 10 at 10:56 Jarliev PérezJarliev Pérez 2621 gold badge8 silver badges21 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

You must use a unique wire:key when displaying data in a loop. The record ID is a good option, but it's best to also add a prefix to avoid conflicts when displaying multiple resources with the same ID on the same page.
The wire:key lets Livewire know which HTML elements have changed when merging the new rendered HTML with the currently displayed HTML.

@foreach($invoices as $invoice)
    <tr wire:key="invoice-{{ $invoice->id }}">
        ....

Here you can find documentation about this behavior

发布评论

评论列表(0)

  1. 暂无评论