Skip to main content
iVentureTeam

task_stage_with_state_selection

In the task list view, the Stage column shows the stage name with the task's state bubble beside it. That pairing is task_stage_with_state_selection, a composite widget that renders two fields in one cell, and it is not the many2one widget it looks like.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 26, 2026Updated August 26, 20265 min read
Technical nametask_stage_with_state_selection
Field typesmany2one
Viewslist (core), form
Moduleproject
Used in core2 occurrences across 1 module: the task list view and the project sharing task list in project
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0
No-code setupNo. Applied in XML; Studio does not list it
Alternativesmany2one, project_task_state_selection, statusbar_duration

What the Stage with state widget does

Task lists in Odoo show more than the stage name in the Stage column: each row also carries the small task state icon, the checkmark, hourglass or cross that project_task_state_selection renders. This widget is the glue that puts both in one cell.

Structurally it is unusual. Most widgets on this site wrap one field; this one is a composite component whose template renders a Many2One for the field it is placed on, stage_id, and a ProjectTaskStateSelection for a second field it fetches itself. The second field's name is hardcoded: fieldDependencies declares state, and the state component receives name: "state" unconditionally.

The state part is passed showLabel: false, so it always renders as a bare icon, and by default it is also passed readonly: true through the widget's one option, which makes the icon informational in lists unless you opt in to editing.

What this means for your team

The reason this widget exists is information density. A task list that shows only stages answers where work sits; adding the state icon answers how it is doing there, approved, changes requested, waiting, done, without an extra column eating horizontal space.

For teams running approval flows on tasks, the pairing matters day to day: a task can sit in the same stage for a week while its state moves from In Progress to Changes Requested to Approved. Reviewers scanning the list see that movement in the Stage column itself.

The default read-only state icon is a sensible guardrail in shared lists: it stops a stray click from flipping a task to Done while still showing the signal. Where a lead actively triages from the list, enabling the click with state_readonly: False turns the column into a working surface.

Supported options in Odoo 19

One option, declared in the widget's own descriptor and verified in the Odoo 19.0 source. Everything else you might expect from a many2one widget is absent by design, see the note below.

OptionTypeWhat it does
state_readonlybooleanControls whether the state icon half is interactive. Defaults to true, so the icon is display-only; pass {'state_readonly': False} to let users change the task state from the same cell. The stage half's editability follows the record as usual. Removed on the Odoo 20 development branch.(default: true)(since Odoo 18.0)

Many2one options do not work here. The descriptor is a bare component, not a spread of the m2o field descriptor, and its extractProps reads only state_readonly and the view type. no_open, no_create, no_quick_create and friends are silently discarded, a trap because the field it sits on is a many2one and the syntax looks like it should work.

Working examples

How core applies it in the task list

<field name="stage_id" invisible="not project_id or not stage_id"
       widget="task_stage_with_state_selection" filters="1"/>

The state field does not need to be added to the view; the widget's fieldDependencies pulls it into the record data automatically.

Making the state icon clickable

<field name="stage_id" widget="task_stage_with_state_selection"
       options="{'state_readonly': False}"/>

The dropdown then behaves exactly like project_task_state_selection: waiting tasks only offer Done and Canceled, and changes save immediately in list view.

What not to write

<!-- no_open is ignored: the descriptor never reads m2o options -->
<field name="stage_id" widget="task_stage_with_state_selection"
       options="{'no_open': True}"/>

Inside the composite: two widgets sharing one cell

Reading the source explains both the power and the constraints of the composite approach.

Two components, one record. The template is four lines: a flex div containing <Many2One t-props="stageProps"/> and <ProjectTaskStateSelection t-props="stateProps"/>. Both prop sets derive from the same standard field props, so both halves read and write the same record; the state half just swaps the field name to state and forces showLabel: false.

The 18 to 19 rewrite is internal only. Odoo 18 passed the props straight into the full Many2OneField component. Odoo 19 switched to the new composition API, computeM2OProps plus the lean Many2One component, part of the framework-wide many2one rework. The registered name, option and behavior are unchanged.

Why the m2o options are dead. Options only reach a widget through its descriptor's extractProps. This descriptor's extractProps returns exactly two props: stateReadonly and viewType. The stage half receives the computed defaults of the m2o machinery, which in 19 means the standard open-on-click and create behaviors, with no way to tune them from XML.

viewType is forwarded deliberately. ProjectTaskStateSelection changes behavior by view, saving immediately in lists and kanbans, so the composite passes the real view type through instead of letting the inner component assume a form.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. The state_readonly option is deleted on the development branch; see below.
Odoo 19.0VerifiedVerified against the shipped source; internal Many2One composition rewrite, same behavior.
Odoo 18.0VerifiedWidget introduced with the state_readonly option.
Odoo 17.0Not availableWidget does not exist; task lists showed a plain stage column.
Odoo 16.0Not availableWidget does not exist.

Upgrade note. Views from Odoo 18 carry to 19 unchanged. Coming from 16 or 17, where the widget does not exist, the equivalent list column was a plain stage_id field; add the widget name during migration if you want the state icon in the column.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026, and the development branch remains unstable until release.

The branch removes the state_readonly option entirely: supportedOptions is gone, extractProps forwards only the view type, and the state component no longer receives a readonly override, so the state icon is always interactive wherever the record itself is editable. XML passing {'state_readonly': ...} will not error, it will simply stop having any effect, flipping today's safe-by-default lists into clickable ones. Worth a note in your 20 migration checklist; we re-verify after release.

Common problems and fixes

SymptomCause and fix
no_open or no_create in options has no effectThe composite descriptor extracts only state_readonly and viewType; many2one options are never read. Use a plain many2one widget if you need those options, or accept the defaults with this one.
The state icon shows but cannot be clickedstate_readonly defaults to true. Pass options="{'state_readonly': False}" on the field.
The widget shows no state icon at allThe companion field is hardcoded to state; on models without a state selection the inner widget has nothing to render. Use it on project.task or a model that defines the same state field; the name cannot be remapped.
Only Done and Canceled appear in the state dropdownInherited project_task_state_selection behavior for tasks in the waiting state, where dependencies control progress. Expected; resolve the blocking dependency to regain the full state list.
The state name never displays, only the iconThe composite passes showLabel false to the state component unconditionally. By design; render a separate state field with hide_label False if you need the text.

Stage with state widget vs the alternatives

WidgetBest forKey difference
task_stage_with_state_selectionTask list columns that should show the stage and the state icon togetherComposite of a many2one and a hardcoded state selection in one cell, with one readonly switch
many2oneA plain stage column with the full m2o option setOne field only, but no_open, no_create and friends actually work
project_task_state_selectionThe task state on its own, in kanban footers or form title areasThe inner state component used alone, with its toggle and dropdown modes
statusbar_durationStage display on the task form with time-in-stage numbersForm-oriented stage bar with durations rather than a compact list cell

Use the composite only where the stage and state belong in the same cell, which in practice means task lists. On forms, core keeps the two fields separate: a statusbar for the stage and the state widget in the title area.

Frequently asked questions

What does the task_stage_with_state_selection widget do?+
It renders the task's stage (a many2one) and the task's state icon side by side in a single cell, as seen in the Stage column of Odoo 18+ task lists. The state field is fetched automatically through fieldDependencies.
Can I choose which field the state icon reads?+
No. The companion field name is hardcoded to state in both fieldDependencies and the component props. The widget is built for project.task and models mirroring its state selection.
Why are my many2one options ignored on this widget?+
Because it is not a many2one descriptor. Its extractProps reads only state_readonly and the view type, so m2o options like no_open pass through unread. That is the widget's biggest gotcha.
How do I let users change the task state from the list?+
Pass options="{'state_readonly': False}". The state dropdown then saves immediately in list view, with the same rules as project_task_state_selection, including the restricted menu for waiting tasks.
What changes for this widget in Odoo 20?+
The development branch removes the state_readonly option altogether, so the state icon becomes always interactive when the record is editable. Existing XML keeps working but the option silently loses effect.

Task lists that show status at a glance?

We build project workspaces where lists, kanbans and dashboards carry exactly the signals your team triages by: stages, approval states, blockers and aging, tuned per role, on Odoo 16 through 19.

Design my task views

How this page was produced

This page was verified by reading project_task_stage_with_state_selection.js and its template in the Odoo 19.0 project module, the same file in 18.0 for the introduction and in the development branch for the option removal, plus both core usages in project_task_views.xml and the project sharing variant. Report corrections via our contact page.