Alexandra Claudia
Alexandra Claudia

Reputation: 39

Communication between filter component and table component in livewire

I have a component that I want to split into two parts, a filtering part and a table part. Now I know I need to somehow use the livewire events, but I am not sure how to create my functions in order to make the query work.

public function render()
    {

        $stations = Station::query()
                    ->search($this->search)
                    ->orderBy($this->sortBy, $this->sortDirection)
                    ->Paginate($this->perPage);


        return view('livewire.workbooks-table', [
            
            'stations' => $stations,
            'stations'=>Station::when($this->byCpm, function($query){
                                $query->Where('CPM', $this->byCpm);
                                })
                                ->when($this->byStartDay, function($query){
                                    $query->Where('StartDay', $this->byStartDay);
                                    })
                                ->when($this->byEndDay, function($query){
                                    $query->Where('EndDay', $this->byEndDay);
                                    })
                                ->when($this->byStartTime, function($query){
                                    $query->Where('StartTime', $this->byStartTime);
                                    })
                                ->when($this->byEndTime, function($query){
                                    $query->Where('EndTime', $this->byEndTime);
                                    })
                                ->when($this->byOwner, function($query){
                                    $query->Where('owner_id', $this->byOwner);
                                    })
                                ->when($this->byFormat, function($query){
                                    $query->Where('format_id', $this->byFormat);
                                    })
                                ->when($this->byMarketCity, function($query){
                                    $query->Where('market_city_id', $this->byMarketCity);
                                    })
                                ->when($this->byMarketState, function($query){
                                    $query->Where('market_state_id', $this->byMarketState);
                                    })
                                ->when($this->minCPM, function($query){
                                    $query->where('CPM', '>=', $this->minCPM.'%');
                                    })
                                ->when($this->maxCPM, function($query){
                                    $query->where('CPM', '<=', $this->maxCPM.'%');
                                    })
                                    ->search($this->search)
                                    ->orderBy($this->sortBy, $this->sortDirection)
                                    ->Paginate($this->perPage),
            
  
        ]);
    }

This is how one of the filter works

<div class="w-1/6 relative mx-1">Format
     <select wire:model="byFormat" class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500" id="grid-state" placeholder="Format">
          <option value="" >Select Format</option>
          @foreach($formats as $format)
             <option value="{{ $format->id }}" >{{ $format->format }}</option>
          @endforeach
    </select>
</div>

And the table is just a regular table. My question would be. Is there a nicer way to do the query such that it's not all in render and I can actually use the events or is there any way I could use the events with what I have right now

Upvotes: 0

Views: 372

Answers (1)

Prospero
Prospero

Reputation: 2352

you can use scope in the model class, like

class Station extends Model
{
 //.....

   public function scopeStartDate($query,$startDate)
   {
      if($startDate)
         return $query->where('byStartDate',$startDate);
      return $query;
   }
   // the same for the others properties to be filtered
}

then, in the controller you can handle in a separated function the data retriever logic

public function getFilteredData()
{
   return Station::
        ->startDate($this->byStartDay)  // from the scope
        ... // add the others 
        ->search($this->search)
        ->orderBy($this->sortBy, $this->sortDirection)
        ->Paginate($this->perPage),
}

public function render()
{
   return view('livewire.workbooks-table', [
            'stations' => $this->getFilteredData()
   ]);
}

Upvotes: 1

Related Questions