Skip to main content
iVentureTeam

todo_done_checkmark

Odoo's personal to-dos mark completion with a single circled check. todo_done_checkmark is a state_selection in disguise, with two pieces of memory the source docs never mention.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 21, 2026Updated August 21, 20266 min read
Technical nametodo_done_checkmark
Field typesselection
Viewsform, list, kanban, activity
Moduleproject_todo
Used in core4 occurrences across 1 module: the to-do list, form, and activity views
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0
No-code setupNo. Applied via the widget attribute in view XML
Alternativesstate_selection, project_task_state_selection, task_done_checkmark, boolean_toggle

What the To-do done checkmark does

Odoo's to-do app stores completion in the task state field, the same five-value selection project tasks use: in progress, changes requested, approved, canceled, done. A personal to-do does not need that machinery on screen; it needs one tick. This widget renders the whole selection as a single circled check that is hollow while the to-do is open and filled once it is done.

Under the hood it subclasses state_selection, so it is still a selection widget with all of that widget's props. What it overrides is presentation and the click. The template drops the dropdown entirely, desktop and mobile variants both render one anchor with a Font Awesome check-circle glyph and a tooltip that flips between "Mark as done" and "Mark as to-do".

The click is a toggle with memory: to done if the state is anything else, and back to the remembered previous state otherwise, so a to-do that was 02_changes_requested returns there when unticked rather than resetting arbitrarily.

What this means for your team

For anyone running their day out of Odoo's to-do list, this widget is the interaction they touch most. Two of its details are worth knowing at the process level.

First, the save behavior differs by view. Ticking a to-do in the list or kanban writes immediately, which is what a checklist should do. Ticking it on the form is a pending edit, committed with the rest of the form. Users who tick and immediately navigate away from a form can lose the tick, and it looks like a bug when it is the standard form edit model.

Second, because the widget writes the shared task state field, done here means done everywhere. To-dos converted to project tasks, or tasks surfaced in the to-do app, carry the state across, and dashboards counting 1_done tasks include ticks made from this checkmark. That makes the humble circle a real data entry point, not a private flag, and it is why the revert behavior preserves the old state instead of guessing.

Supported options in Odoo 19

Verified against todo_done_checkmark.js in the Odoo 19.0 project_todo module. The widget declares no options of its own; it inherits the pair below from state_selection. Note that the base widget's dropdown-related behaviors have no visible effect here since the dropdown is gone.

OptionTypeWhat it does
autosavebooleanInherited from state_selection and honored only on the list/kanban path, where the click goes through updateRecord. Form clicks bypass it entirely. Deleted upstream on the Odoo 20 development branch.(default: true)
hide_labelbooleanInherited from state_selection but visually moot: the custom template renders only the icon, so no label appears either way.

hide_label is effectively moot. The custom template never renders a label at all, so the inherited option changes nothing visible. It is listed because the prop pipeline still accepts it; do not expect a label to appear by setting it to False.

Working examples

As core uses it in the to-do list

<field name="state" widget="todo_done_checkmark" nolabel="1" width="20px"/>

On the to-do form next to priority stars

<field name="priority" class="h3 pe-2" widget="priority_switch"/>
<field name="state" widget="todo_done_checkmark" class="o_task_state_widget"/>

This pairing is the whole to-do header UI in core: stars for priority, circle for done.

On a custom model

<field name="state" widget="todo_done_checkmark"/>

Works only if the selection actually contains a 1_done value and, for a sensible fallback, 01_in_progress; both value strings are hardcoded in the toggle logic.

Two state flags and one if statement

The component keeps two flags of local state, and both exist to stop the icon from lying.

notDoneState is the memory. Captured once in onMounted: the field's current value, unless that value is already 1_done, in which case it falls back to 01_in_progress. This is what an unticked to-do returns to. Because it is captured at mount, a state changed elsewhere after load does not update the memory until the view rerenders the component.

notReloadState is the hover freeze. Mouseover sets it, mouseleave clears it, and while it is set the rendered done/not-done appearance refuses to sync with the record. The effect: as you click, the glyph under your cursor does not instantly flip and shift the layout; it settles when the mouse leaves. A tiny piece of UI craft entirely invisible in the docs.

The save split is one if statement. onDoneToggled calls the inherited updateRecord, which honors autosave and saves, only when viewType is kanban or list; otherwise it calls record.update, a pending edit. The viewType arrives through a custom prop the descriptor's extractProps adds, a pattern worth copying when a custom widget needs to know its host view.

Note the hardcoded strings: 1_done and 01_in_progress are literals in the source. This widget is not generic; it is welded to the task-state vocabulary.

Version compatibility

VersionStatusNotes
Odoo 20.0Partial / changedNot released. viewType check renamed kanban to card and the inherited autosave option is deleted upstream; details below.
Odoo 19.0VerifiedVerified against the shipped source.
Odoo 18.0VerifiedIdentical to 19.0 apart from code style.
Odoo 17.0VerifiedWidget introduced with the to-do app; same behavior.
Odoo 16.0Not availableThe project_todo module does not exist.

Upgrade note. Introduced with the to-do app in Odoo 17; the 17, 18, and 19 files differ only in code style. Nothing to migrate between those versions. Coming from 16, the to-do app itself does not exist there.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. These notes are read from the public development branch, which is unstable until feature freeze; we re-verify against the shipped release.

Two changes are visible. The immediate-save check swaps kanban for card, following the framework-wide kanban-to-card rename, so the widget saves immediately in card and list views. And the props migrate to the new validation system, with the component now spreading standardFieldProps plus optional showLabel, withCommand, and viewType.

Upstream of it, the base state_selection deletes its autosave option on master, which trims this widget's inherited option surface too. The toggle logic, the hardcoded state strings, and the hover freeze are all unchanged.

Common problems and fixes

SymptomCause and fix
Tick disappears after leaving the to-do formOn forms the click is a pending edit, saved only with the form. Save the form, or tick from the list or kanban where the widget saves immediately.
Unchecking restores a state the user did not expectThe widget returns to the state captured when the view loaded, or falls back to in progress if it loaded as done. No fix needed; this is the designed memory behavior.
The icon does not update while hovering over itThe appearance is frozen under the mouse to prevent mid-click glyph flips. Move the pointer away; the icon syncs on mouseleave.
Widget errors or misbehaves on a custom selection fieldThe values 1_done and 01_in_progress are hardcoded in the toggle logic. Use it only on selections containing those exact values, or subclass with your own values.
Widget not found on a database without the to-do appRegistration lives in project_todo, not web or project. Install project_todo or use state_selection instead.

To-do done checkmark vs the alternatives

WidgetBest forKey difference
todo_done_checkmarkDone/not-done ticking on personal to-dosWhole state machine collapsed into one remembering toggle
state_selectionStatus bubbles with the full dropdownExposes every state; label hidden by default
project_task_state_selectionProject task states with waiting logicState machine aware, restricts choices for waiting tasks
task_done_checkmarkBoolean done flags on project milestonesSame idea built on boolean_toggle rather than a selection
boolean_togglePlain self-saving switchesGeneric toggle, no state memory

Use this widget only where the full state vocabulary would be noise and done/not-done is the real question. The moment users need to request changes or approve, fall back to the state selection widgets.

Frequently asked questions

What field does todo_done_checkmark work on?+
The task state selection. The toggle writes the literal value 1_done and restores the remembered previous state on untick, falling back to 01_in_progress. Those strings are hardcoded, so the widget only suits selections using the task-state vocabulary.
Does ticking a to-do save immediately?+
In list and kanban views yes, through the inherited updateRecord path. On the form it is a pending edit like any other field and commits when the form saves. The split is an explicit viewType check in the source.
What happens when I untick a done to-do?+
It returns to the state it had when the view loaded. If it was already done at load, the widget cannot know the older state and falls back to in progress.
Why does the checkmark wait until my mouse leaves to update?+
The component deliberately freezes its appearance on mouseover and syncs on mouseleave, so the icon does not flip underneath your cursor mid-click. It is cosmetic; the value itself updates immediately.
Is todo_done_checkmark the same as task_done_checkmark?+
No. This one lives in project_todo and toggles the state selection. task_done_checkmark lives in project, extends boolean_toggle, and drives a boolean field. They share the visual idea, not the implementation.
Anything changing in Odoo 20?+
The development branch renames the immediate-save check from kanban to card and migrates props to the new validation system; the base state_selection also loses its autosave option upstream. All unreleased until September 2026, and we re-verify then.

To-dos fine, but tasks stuck?

A tidy done-circle will not fix a messy task flow. We configure Odoo project and to-do workflows end to end: states, automations, recurring tasks, and the reporting that shows what actually got done, on Odoo 16 through 19.

Book a free consultation

How this page was produced

This page was verified by reading todo_done_checkmark.js and its XML template on the Odoo 19.0 branch, plus the base state_selection_field.js for inherited options, and diffing against 17.0, 18.0, and master. The toggle memory, hover freeze, and per-view save behavior are all taken from the component source and exercised on a clean Odoo 19 database, where the screenshot was captured. Corrections welcome via our contact page.