1
votes

I have a simple Livewire component, like the following

use Livewire\Component;

class KandidaatList extends Component
{
    public $kandidaten = [];

    public function mount()
    {
        $this->kandidaten = '[
        {
          "naam" : "Aad Elias",
          "geslacht": "m",
          "leeftijd": "35",
          "woonplaats": "Groningen",
        },
        {
          "naam" : "Linda de Jong",
          "geslacht": "v",
          "leeftijd": "24",
          "woonplaats": "Mantgum",
        }
      ]';
    }
}

Blade/View

<div>
    @foreach (json_decode($kandidaten) as $kandidaat)
      <div class="pl-14 py-5 border-b border-grey-600 flex justify-around">
        <div>{{$kandidaat->naam}}</div>
        <div>{{$kandidaat->leeftijd}}</div>
        <div>{{$kandidaat->woonplaats}}</div>
        <div class="c-tag c-tag--primary h-5">{{$kandidaat->status}}</div>
      </div>
    @endforeach
</div>

Now I would like to add a feature so I can filter through the array. For example, if I would type in the name Aad Elias that only results with that name show up.

I've generated a component that holds a search query, like the following.

namespace App\Http\Livewire;

use Livewire\Component;

class Search extends Component
{
    public $query;
    
    public function mount()
    {
      $this->query = 'search query';
    }
}

And for now, I can output the typed a query in the Blade.

<div>
    <input wire:model="query" type="text">
    {{ $query }}
</div>

But how do I connect the query I type in this input field with the array from KandidaatList to return only results with the searched name?

1

1 Answers

1
votes

If you're working on an array as per your example, I would parse it to a collection so that you get access to all the helper methods which makes working with arrays much simpler. Then you can leverage some of the collection functions to filter your results.

$results = collect(json_decode($kandidaten))->reject(function($item) use ($query) {
    return !preg_match("#^'. $query .'#i', $item->naam);
});

What we're doing above is converting the array to a collection and then using the reject function to return a new collection of results where the name property begins with $query.

If you're working with Eloquent models and the database, the first thing I would do is define a $results computed property, benefit of this is it gets cached per request so calling $results x times will not make separate database calls.

public function getResultsProperty()
{
    return $this->search($this->$query);
}

Then define a search function which is used by the $results computed property.

public function search()
{
    return Kandidaten::where('naam', 'like', "{$this->query}%")->get();
}

Note: I purposefully excluded a % from the start of the like, but you can make whatever search makes sense for your use case.

Your Livewire component view would remain mostly the same, just replacing the content of your @foreach.

<div>
    @foreach ($this->results as $kandidaat)
      <div class="pl-14 py-5 border-b border-grey-600 flex justify-around">
        <div>{{$kandidaat->naam}}</div>
        <div>{{$kandidaat->leeftijd}}</div>
        <div>{{$kandidaat->woonplaats}}</div>
        <div class="c-tag c-tag--primary h-5">{{$kandidaat->status}}</div>
      </div>
    @endforeach
</div>