Drew
Drew

Reputation: 251

How to re-render a table with Livewire after an event emitted from another component

I'm new to Livewire and I am stuck with this problem.

I've created a table.blade.php component with livewire, and another searchbar.blade.php component, which is not a child of the table component. Every time a search for a term, the table should rerender with the seached parameter.

All is right, and the search query gives the correct result (clients with pagination), but somehow the table does not rerender the html.

Any ideas what I'm doing wrong? Thanks

<div>
    <input type="text" wire:model="query" autofocus>
</div>
class SearchBar extends Component
{
    public $query;


    public function updatedQuery()
    {
        $this->emit('searchForQuotes', $this->query);
    }

    public function render()
    {
        return view('livewire.clients.searchbar');
    }
}
<div>
    <table>
        <tbody>
        @foreach($clients as $client)
            @livewire('clients.row', ['client' => $client], key($client->id))
        @endforeach
        </tbody>
    </table>
</div>
class Table extends Component
{
    use WithPagination;

    public $query;

    protected $listeners = [
        'searchForQuotes' => 'render'
    ];

    public function mount()
    {
        $this->resetData();
    }

    public function resetData()
    {
        $this->query = null;
    }

    public function render($query = null)
    {
        $q = Client::query();

        if ($query) {
            $q->whereRaw("CONCAT(surname, ' ', name) LIKE '%" . $query . "%'");
        }

        $clients = $q->latest()->paginate(20);

        return view('livewire.clients.inc.table', [
            'clients' => $clients, 'query' => $query
        ]);
    }
}

Upvotes: 0

Views: 2045

Answers (3)

Yinci
Yinci

Reputation: 2510

You can make your child components reactive by making your key() unique every render of the parent:

@livewire('clients.row', ['client' => $client], key($client->id . "-" . Str::random()))

By adding a Str::random(), the key is different every time the parent updates, which forces the children to update as well. This also works with now(), but only as long as you have a prefix. It is important to note that this causes more requests and thus can make your table slower.

Upvotes: 1

Drew
Drew

Reputation: 251

I think I found the problem, but don't know how to solve it. I the table.blade.php component I've got this code.

@foreach($clients as $client)
   @livewire('clients.row', ['client' => $client], key($client->id))
@endforeach

It seems like the nested component are not rendering after firing the event.

Upvotes: 0

GrayhoundButPurple
GrayhoundButPurple

Reputation: 582

Try something like this :

class Table extends Component
{
use WithPagination;

public $query;

protected $listeners = ['searchForQuotes'];

public function mount()
{
    $this->resetData();
}

public function searchForQuotes($query)
{
    $this->query = $query; 
    // Do something
    $this->render();
}

public function resetData()
{
    $this->query = null;
}

public function render()
{
    $q = Client::query();

    if ($this->query) {
      $q->whereRaw("CONCAT(surname, ' ', name) LIKE '%" . $query . "%'");
    }

    $clients = $q->latest()->paginate(20);

    return view('livewire.clients.inc.table', [
        'clients' => $clients, 'query' => $this->query
    ]);
}
}

Upvotes: 0

Related Questions