skip to Main Content

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
        ]);
    }
}

3

Answers


  1. Chosen as BEST ANSWER

    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.


  2. 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
        ]);
    }
    }
    
    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search