Skip to main content
Todo List combines a task checklist with animated completion, optional subtasks and configurable editing. Start with a few fixed tasks, or add search and measured virtualization for a longer list.

Try the component

Check tasks, try celebrations and compare pagination with infinite scrolling.

Saving form data

Store the task list in a JSON column with an Eloquent array cast.

First checklist

The default includes animated checkmarks, hand-drawn strikethroughs, completion sounds, an undo notification and a fireworks celebration when all available tasks are complete. To start with a quiet checklist:

Task options

options() accepts an array or a closure. Array keys become stable task identifiers unless the row provides its own id. Use identifiers that remain consistent when the form is reopened.
Generated child IDs use parent-id:child-key. Explicit child IDs must also be unique across the whole field. Checking a parent completes its unlocked children. Changing a child recalculates the parent; locked children are never changed by a cascade. Completion limits count parent tasks, not each child separately.

Create and edit tasks

The edit modal uses FLEX Text Input for its fields. The edit button immediately shows a spinner while the modal is requested. Repeated clicks during that request do not open duplicate modals. With deleteConfirmation(), cancellation leaves the task unchanged and deleteUsing() runs only after confirmation. A rejected callback keeps the task in place; locked tasks cannot be removed. Client-submitted labels are displayed as text, never interpreted as HTML. Invalid or empty creation/edit input is not committed.

Search and long lists

Search matches titles and descriptions, including child tasks. The search box shares the FLEX Text Input presentation. Local search returns to the first page and resets the list scroll position.

Remote loading

remoteLoader('loadTodoPage') calls a public method on the containing Livewire component. The method receives a one-based page number and the search text. For browser loaders, the same name can refer to a function on window; that function also receives { signal } for cancellation.
Return a list of task rows, or explicitly describe whether another page exists:
With bare-array responses, a full page means more results may exist; a shorter page ends loading. Use hasMore when the server knows the answer. Duplicate root IDs already loaded are retained with their local edits; duplicate IDs within a response or collisions with another task’s child ID are rejected. Failed requests display a retry action. Out-of-order responses and responses belonging to a disposed field cannot replace newer results.
Remote loading retains visited task rows and their changes in field state. Submission contains loaded tasks, not every task in the database. Apply ownership checks, filtering and authorization in your loader and persistence callbacks. A field’s UI policy is not a database authorization policy.

Reorder tasks

Drag a parent group’s handle using a pointer or touch. Focus the handle and use Up/Down to reorder with a keyboard. Child tasks move with their parent. A drag preview follows the pointer, and an insertion line marks the destination. Press Escape to cancel. Locked groups keep their positions; keyboard moves skip them. persistCompletedOrder(true) displays completed groups after unfinished ones when reordering is off. Reordering is disabled during search and when virtualization, pagination or infinite scrolling is enabled. This avoids presenting a partial collection as though it were a complete ordering. The default movement duration is 200 milliseconds. A rejected reorderUsing() callback leaves the prior order intact.

Completion feedback

Built-in effects are fireworks, confetti, sparkles, meteors and bloom. Per-task celebrations can differ within one field. Users requesting reduced motion receive completion state changes without motion effects. Bundled audio is resolved through the component’s published resource registry. Sound files are requested on playback, not preloaded for every task. Follow installation to publish assets after installing or updating FLEX.

Register a custom celebration

After the Todo List module is available, register an effect through its public browser API. Return a handle with stop() to release every frame, listener and canvas resource you create.

Persistence callbacks

Tasks normally save with the surrounding form. Callbacks can instead persist individual operations. Return null from create/edit or false from delete/reorder to cancel the requested operation.
deleteUsing() receives all child IDs when deleting a parent. reorderUsing() receives current task contents in the requested order; supplied row contents do not override current server values. Scope database queries and authorize records inside callbacks. For atomic changes across multiple records, use a database transaction. For whole-field synchronization, the standard live()->afterStateUpdated() integration is also available. Avoid persisting the same change twice by enabling both approaches unintentionally.

Validation and database storage

Limits accept zero and must resolve to integers from 0 to 10,000, or null to remove the limit. The overall tree is bounded to 10,000 nodes, including children. Submitted data is checked on the server for valid structure, text lengths, supported boolean values, unique IDs, permitted task IDs, locked completion states and completion/item counts. Invalid data is reported rather than silently dropped. Store tasks in a JSON column with an array cast:
The saved value is a list of structured task rows with string IDs, boolean completion flags and children. A legacy list of configured IDs can be hydrated as completed tasks, but new saves use structured rows. Configured lock and feedback metadata comes from server options. Validate record access in your application before saving or running persistence callbacks.

Keyboard, mobile and appearance

  • Focus a task and press Space or Enter to toggle it. Up/Down and Home/End navigate visible parent tasks.
  • Focus a reorder handle and use Up/Down to move a group where reordering is enabled.
  • Press Enter in the new-task title to save, or move to its description when enabled. Escape cancels creation.
  • Touch layouts expose task actions without requiring a mouse hover.
  • RTL uses logical spacing and reverses pagination arrow presentation. Light and dark colors follow the field’s styles and Filament accent.
  • Changing search, resizing or returning from another tab reuses the field’s keyed rows; inactive surfaces load through FLEX’s normal activation lifecycle.
Use standard Filament options such as label(), helperText(), disabled(), columnSpan(), default() and additional rules() alongside this API.
Last modified on October 16, 2026