Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Category ToggleGroup and Tasks Filter

Premium
9 min read

This lesson will tackle two things: choosing categories for the tasks in the form/table and filtering the tasks by category.


Create Task Form: Choose Category

First, we need to modify the Controller to use Categories. I will add the code for both Create and Edit forms right away.

app/Http/Controllers/TaskController.php

use App\Models\TaskCategory;
 
// ...
 
public function create()
{
return Inertia::render('Tasks/Create');
return Inertia::render('Tasks/Create', [
'categories' => TaskCategory::all(),
]);
}
 
// ...
 
public function edit(Task $task)
{
$task->load(['media']);
$task->load(['media', 'taskCategories']);
$task->append('mediaFile');
 
return Inertia::render('Tasks/Edit', [
'task' => $task,
'categories' => TaskCategory::all(),
]);
}
// ...

Next, we need to add task_categories to the Task type:

resources/js/types/index.d.ts

// ...
 
export interface Task {
id: number;
name: string;
is_completed: boolean;
due_date?: string;
mediaFile?: MediaFile;
task_categories: TaskCategory[];
created_at: string;
updated_at: string;
}

Then, we can add the parameter to our Create page. For selecting the categories for the task, there are many UI options like Select or Ratio, but I've chosen to try an interesting Shadcn component called Toggle Group. It is described as "A set of two-state buttons that can be toggled on or off."

npx shadcn@latest add toggle-group

Interesting point: when installing, it prompted me to override the existing components. You may choose Yes to update them with the newest component versions, but if you made any manual changes to the components, you should probably choose No:

We add this component to the Create form, along with other required changes.

resources/js/Pages/Tasks/Create.tsx

import { type BreadcrumbItem } from '@/types';
import { type BreadcrumbItem, type TaskCategory } from '@/types';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
 
// ...
 
type CreateTaskForm = {
name?: string;
due_date?: string;
media?: string;
categories?: string[];
};
 
export default function Create() {
export default function Create({ categories }: { categories: TaskCategory[] }) {
const taskName = useRef<HTMLInputElement>(null);
 
const { data, setData, errors, post, reset, processing, progress } = useForm<Required<CreateTaskForm>>({
name: '',
due_date: '',
media: '',
categories: [],
});
 
// ...
 
<div className="grid gap-2">
<Label htmlFor="due_date">Categories</Label>
 
<ToggleGroup type="multiple" variant={'outline'} size={'lg'} value={data.categories} onValueChange={(value) => setData('categories', value)}>
{categories.map((category) => (
<ToggleGroupItem key={category.id} value={category.id.toString()}>
{category.name}
</ToggleGroupItem>
))}
</ToggleGroup>
 
<InputError message={errors.due_date} />
</div>
 
// ...

Behind the scenes, I've added three categories to the database:

With those, here's the visual result for the Create Task form:


Saving Data to the DB

We need Controller and Form Request changes:

app/Http/Requests/StoreTaskRequest.php

public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'due_date' => ['nullable', 'date'],
'media' => ['nullable', 'file', 'max:10240'],
'categories' => ['nullable', 'array'],
'categories.*' => ['exists:task_categories,id'],
];
}

In our Controller, we will swap from...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

LA
Luis Antonio Parrado ✓ Link copied!

You forget put

'tasks' => Task::query()
    ->with('media', 'taskCategories')   //Missing
    ->when(....)

in the task query

M
Modestas ✓ Link copied!

Thanks for letting us know! I've updated the lesson!

AF
Angel Fabian Silvera ✓ Link copied!

I change the styles for see in light mode the selecteds

<ToggleGroupItem key={category.id} value={String(category.id)} className="data-[state=on]:bg-primary data-[state=on]:text-primary-foreground data-[state=on]:border-primary">
  {category.name}
</ToggleGroupItem>

Put in Edit and Create And in Dark mode we need styles for see the text

 {task.task_categories?.map((category: TaskCategory) => (
 <span key={category.id} className="rounded-full bg-gray-200 px-2 py-1 text-xs **dark:text-black**">
         {category.name}
 </span>
))}