Reputation: 39
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
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