@martinbean Here is what i have so far, I created a post route "project/get-filter-values", with payload {key and context}, where key is the name of the column which we want the unique values for, context is basically an object with keys as column names and value and the currently selected values by the user, I am using this to apply filters from other columns as well, an example value context will be as follows
{
"context": {
"status": {
"items": [
"completed",
"in_progress"
]
}
}
}
on the controller i run following query
$payload = $request->validate([
'key'=>'required'
]);
$query = Project::query();
$respone;
if($request['context']){
// Loop through the filter items context and apply filters
foreach ($request['context'] as $column => $filter) {
if ($column !== $payload['key'] && isset($filter['items'])) {
$query->whereNotIn($column, $filter['items']);
}
}
$response = $query->select($payload['key'])->distinct()->get();
}
else{
$response = Project::select($payload['key'])->distinct()->get();
}
return response()->json($response);
I created another post route as below
Route::post('project', [ProjectController::class, 'index'])->name('project.filter');
Which basically calls the index method of the controller, on the controller i have following logic
public function index(Request $request)
{
$query = Project::query();
$respone = [];
$page = 1;
if($request->page) $page = $request->page;
if($request['context']){
foreach ($request['context'] as $column => $filter) {
if (isset($filter['items'])) {
$query->whereNotIn($column, $filter['items']);
}
}
$response = $query->paginate(10, ['*'], 'page', $page)->onEachSide(1);
}
else{
$response = $query->paginate(100, ['*'], 'page', $page)->onEachSide(1);
}
return inertia('Project/Index', [
"projects" => ProjectResource::collection($response),
"context" => $request['context']
]);
}
i am using whereNotIn assuming that initially, every project is displayed hence all checkboxes in the filter menu are checked, when user de-selects few values, it means user wants to see all project but the one deselected.
On the react side, i maintain this context object as a react state and pass it to the request.
However i have following doubts:
- What if user deselects all the values and just selects one value, in that case the whereNotIn will receive a big array and query might fail.
- is this an efficient way? wanted to get ideas from the community
- How to make it persistant, such that if user refreshes page, previously applied filter should reapply automatically
- How to make the pagination work, because right now, if click second page, it makes a get request hence all filters are lost