laracasts-livewire-datatable icon indicating copy to clipboard operation
laracasts-livewire-datatable copied to clipboard

Livewire data table sorting by field not working...

Open mvpopuk opened this issue 4 years ago • 4 comments

I have tried to make this sorting thing work in my data table but no luck so far.

This is my code:

CustomersTable.php


namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithPagination;

class CustomersTable extends Component
{
    use WithPagination;

    public $perPage = 10;
    public $sortField;
    public $sortAsc = true;
    public $search = '';


    /**
     *  Livewire Lifecycle Hook
     */
    public function updatingSearch(): void
    {
        $this->gotoPage(1);
    }

    public function sortBy($field)
    {
        if ($this->sortField === $field)
        {
            $this->sortAsc =! $this->sortAsc;
        } else {
            $this->sortAsc = true;
        }

        $this->sortField = $field;
    }

    public function render()
    {
        return view('livewire.customers-table', [
            'customers' => \App\Models\Customers::search($this->search)
                ->orderBy($this->sortField, $this->sortAsc ? 'asc' : 'desc')
                ->paginate($this->perPage),
        ]);
    }
}

customers-table.blade.php

    <div class="animated fadeIn">

        <div class="row mt-2">
            <div class="col-lg-12">
                <div class="card rounded">

        <div class="card-header rounded-top pb-2">
            <p class="d-inline align-middle float-left pt-1 font-weight-bold"><i class="icon-people"></i> Customers</p>

            <div class="d-inline align-middle float-right">
                <a href="/customers/create" class="btn btn-success rounded mt-0"><i class="icon-plus"></i> Add New Customer</a>
            </div>

            <div class="input-group col-4 float-right">
                <input type="text" wire:model="search" class="form-control rounded-left border-right-0 font-italic" placeholder="Type in and search..."  >
                <span class="input-group-addon bg-white border-left-0 rounded-right"><i class="fa fa-search"></i></span>
            </div>

        </div>

    <div class="card-body pb-0">

    @if(count($customers) < 1)
            <div class="float-left mb-4">
            <h6 class="d-inline">No customer found</h6>
            <a class="ml-3 align-middle btn btn-success rounded" href="/customers/create"><i class="icon-plus"></i> Add Customer</a>
    </div>
        @else

        <table class="table table-responsive-sm table-bordered">  <!-- table-sm !-->
    
            <thead>

            <tr>
            <th><a wire:click.prevent="sortBy('id')" role="button" href="#">
                        ID
                        @include('inc.sort-icon', ['field' => 'id'])
                    </a></th>
                <th><a wire:click.prevent="sortBy('FirstName')" role="button" href="#">
                        Name
                        @include('inc.sort-icon', ['field' => 'FirstName'])
                    </a></th>
                <th><a wire:click.prevent="sortBy('Gender')" role="button" href="#">
                        Gender
                        @include('inc.sort-icon', ['field' => 'Gender'])
                    </a></th>
                <th><a wire:click.prevent="sortBy('Phone')" role="button" href="#">
                        Phone
                        @include('inc.sort-icon', ['field' => 'Phone'])
                    </a></th>
                <th><a wire:click.prevent="sortBy('Email')" role="button" href="#">
                        Email
                        @include('inc.sort-icon', ['field' => 'Email'])
                    </a></th>
                <th><a wire:click.prevent="sortBy('Address')" role="button" href="#">
                        Address
                        @include('inc.sort-icon', ['field' => 'Address'])
                    </a></th>
                <th><a wire:click.prevent="sortBy('created_at')" role="button" href="#">
                        Created at
                        @include('inc.sort-icon', ['field' => 'created_at'])
                    </a></th>
                <th>Action</th>
            </tr>
            </thead>
            <tbody>

           
            @foreach($customers as $customer)

                <tr>
                    <td>{{ $customer->id }}</td>
                    <td><a href="/customers/{{ $customer->id }}/edit"> {{ $customer->FirstName }} {{ $customer->LastName }}</a></td>
                    <td>{{ $customer->Gender }}</td>
                    <td>{{ $customer->Mobile }}</td>
                    <td>{{ $customer->Email }}</td>
                    <td>{{ $customer->Address }}, {{ $customer->City }}</td>
                    <td>{{ $customer->created_at }}</td>

                    <td>
                        <div class="d-inline float-left mr-1">
                            <a class="btn btn-primary btn-sm rounded" href="/jobs/{{ $customer->id }}/create">New Job</a>
                        </div>

                        <div class="d-inline float-left mr-1">
                            <a href="/customers/{{ $customer->id }}/edit" class="btn btn-secondary btn-sm rounded">Edit</a>
                        </div>

                        <div class="d-inline float-left mr-1">
                            {!!Form::open(['action' => ['CustomersController@destroy', $customer->id], 'method' => 'POST'])!!}
                            {{Form::hidden('_method', 'DELETE')}}
                            {{Form::submit('Delete', ['class' => 'font-weight-bold align-middle btn btn-danger btn-sm rounded'])}}
                            {!!Form::close()!!}
                        </div>

                    </td>
                </tr>

            @endforeach

            </tbody>

        </table> <!-- end of Table !-->

            <div class="float-left">
            {{ $customers->links() }}
            </div>
            
            <div class="float-right text-muted pb-3">
                Showing {{ $customers->firstItem() }} to {{ $customers->lastItem() }} out of {{ $customers->total() }} customers
            </div>
            @endif  
        </div> <!-- end of Card Body !-->
    </div>
</div>

the routes/web.php

Route::resource('customers', 'CustomersController');

Which points to CustomersController@index which I think it doesn't affect anything in any way since the index function looks like this:

public function index()
 {
        return view('customers.index'); 
    
}

customers/index.blade.php

@section('content')
    @livewire('customers-table')
@endsection

The search is working just fine, the pagination is also working fine, the sorting is not.

GIF 4-27-2020 9-34-15 PM

I apologise for the big chunk of code I posted but, if someone will ever read this, I want him to have the entire context...

Happy coding folks. Livewire is great, I just don't fully understand it... I find it hard to debug since the ajax calls are being made... no errors no nothing... it's just not working.

If anyone will even consider to help me out on this one... thanks so much for your time. I owe you big time.

mvpopuk avatar Apr 27 '20 19:04 mvpopuk

@mvpopuk please refer https://laravel.com/docs/7.x/scout#searching for a search to be work. the search method is defined in laravel scout package.

shamsher73 avatar Apr 28 '20 03:04 shamsher73

It's not the search that isn't working, it's the table sorting bit.

mvpopuk avatar Apr 28 '20 03:04 mvpopuk

If I take the search() out of the render function, the sorting Is working

mvpopuk avatar Apr 28 '20 13:04 mvpopuk

I am facing same issue described by @mvpopuk , can anyone please explain the solution?

usamadevop avatar Feb 04 '23 06:02 usamadevop