Skip to main content
iVentureTeam

char_with_placeholder_field_to_check

The widget behind Odoo 19's To review pill on journal entry lists: a char field that flags posted, unreviewed entries to accountants, and quietly disappears again in Odoo 20.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 25, 2026Updated August 25, 20266 min read
Technical namechar_with_placeholder_field_to_check
Field typeschar, text
Viewslist (core), form
Moduleaccount, installed with Invoicing or Accounting
Used in core2 occurrences in 1 module: the entry number column of two account.move list views
VersionsOdoo 19.0
No-code setupNo. Applied in view XML only; Studio has no toggle for it
Alternativeschar_with_placeholder_field, badge, account_document_state

What the To review badge widget does

Odoo's accounting has a review workflow built around a boolean field called checked on journal entries: entries needing attention show up under a To Check filter until an accountant marks them reviewed. Odoo 19 made that state visible directly in the entry lists, and this widget is how.

char_with_placeholder_field_to_check wraps the entry number column. It subclasses char_with_placeholder_field, inheriting its one trick, showing the placeholder as a muted value when the field is empty, and adds a single element: a rounded blue badge reading To review, rendered after the number when the entry is posted but not yet reviewed.

The condition is precise. The badge appears when record.data.checked === false and record.data.state === 'posted'. A draft entry never shows it, and neither does a record where checked simply was not loaded, because JavaScript's undefined is not strictly equal to false. On top of that the badge node carries groups="account.group_account_user", so only full accountants see it; invoicing-only users get a plain number column.

What this means for your team

Review queues fail when the queue is a filter people must remember to open. Surfacing the To review flag inline, in the list accountants already work in, converts the review step from a separate chore into something you clear as you go. That is the entire point of this widget, and during a close it is a genuinely useful nudge.

For teams building their own review or approval flows on other models, quality checks, contract vetting, HR validations, this widget is the reference pattern for a list-level status nudge: a boolean on the record, an invisible companion field in the view, a badge gated by state and by access group. We reuse that structure regularly in custom Odoo workflow work because it is cheap, discoverable and does not touch the model's logic at all.

One managerial note: the badge is visible only to members of the Accountant group. If your reviewers are configured with lighter access rights, they will never see the nudge, and adoption of the review workflow will quietly stall. Check group membership before concluding the feature does not work.

Supported options in Odoo 19

The widget declares no options of its own; its descriptor spreads charWithPlaceholderField, which itself spreads the standard char field. The inherited knobs below are verified against the 19.0 source chain. The badge itself has no option, no attribute and no context key; its condition is hardcoded.

OptionTypeWhat it does
placeholder_fieldfield nameInherited from the char field. A char field on the record whose value serves as a dynamic placeholder. The base widget then displays that placeholder as a muted value when the field is empty.
dynamic_placeholderbooleanInherited from the char field's extractProps. Enables the dynamic placeholder popup used in template-editing contexts; irrelevant on entry lists but technically present.

The companion field is the real configuration. The badge only works if the view loads checked. Core does this with an invisible column and a comment: <field name="checked" column_invisible="True" groups="account.group_account_user"/>. Drop that line from a customized view and every badge silently disappears, with no error anywhere.

Working examples

How core uses it (Journal Entries list, Odoo 19)

<field name="name"
       widget="char_with_placeholder_field_to_check"
       placeholder="/"
       readonly="state != 'draft'"/>
<field name="checked" column_invisible="True"
       groups="account.group_account_user"/>
<!-- core's own comment: To be used for Reviewed badge display -->

Reusing the pattern on a custom review flow

<field name="reference" widget="char_with_placeholder_field_to_check" placeholder="/"/>
<field name="checked" column_invisible="True"/>
<field name="state" column_invisible="True"/>

The field names are not configurable: the template reads checked and state literally, and the state must be the string posted. A custom model must mirror those names and values, or you subclass the template with your own condition.

One template, two widgets: how the badge is wired

Two implementation details make this widget more interesting than its size suggests.

The badge lives in the base widget's template. The component class sets static template = "account.CharWithPlaceholderField", the base template, not a template of its own. The badge arrives through a t-inherit with t-inherit-mode="extension", which modifies account.CharWithPlaceholderField itself rather than deriving a new template. The practical consequence: any usage of the base char_with_placeholder_field widget also carries the badge markup, and on the same Journal Entries screens core does use the base widget for the Number column of another list. Records there simply fail the checked === false test when the view does not load the field, which is the only thing keeping the badge from leaking. It is a fragile equilibrium worth knowing about before you add checked to a view that uses the base widget.

The strict comparison is the safety net. undefined === false is false in JavaScript, so a view that forgets the companion field degrades to a plain number column instead of spraying badges on every posted entry. The same strictness means a custom model whose review flag is named anything other than checked gets no badge at all.

And one for the code archaeologists: the file is named char_with_placeholder_field_to_check_to_check.js, the suffix pasted twice, while the directory has it once. Harmless, but a reminder that this corner of the codebase was assembled quickly, which fits how briefly it lived.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. The development branch deletes the widget and reverts both views to char_with_placeholder_field. Re-verified after launch.
Odoo 19.0VerifiedIntroduced in Odoo 19; behavior verified against the shipped source.
Odoo 18.0Not availableThe widget does not exist. The checked field already exists on account.move, but the lists use the base widget with no badge.
Odoo 17.0Not availableNeither this widget nor its base widget exists.
Odoo 16.0Not availableThe widget does not exist.

What is changing in Odoo 20

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

The widget is deleted. The entire char_with_placeholder_field_to_check directory is gone from the development branch. Both list views that used it now pass the plain char_with_placeholder_field widget, and the invisible checked companion line next to them is removed as well. The inline To review badge, as implemented here, has no direct successor in those views at the time of writing.

The base widget survives. char_with_placeholder_field continues to exist and even gains usages on the development branch, so only the badge subclass is affected.

If a customization references the widget name, an upgraded database will log a missing-widget warning and fall back to the default char rendering, number still visible, badge gone. Fold the swap into your Odoo 20 migration checklist rather than discovering it in production.

Common problems and fixes

SymptomCause and fix
No To review badges anywhere, even on posted unreviewed entriesThe view does not load the checked companion field, so record.data.checked is undefined, which fails the strict === false test. Add <field name="checked" column_invisible="True"/> to the list, as core does.
Some users see badges and others do notThe badge node is gated by groups="account.group_account_user". Expected. Grant the Accountant access level to reviewers who should see it.
Badges appear on a column using the plain base widgetThe badge is injected into the shared base template by extension-mode inheritance, and that view loads checked and state fields that satisfy the condition. Remove the companion fields from that view, or accept the badge; the markup is shared by design.
Draft entries never show the badgeThe condition requires state to be exactly 'posted'. Expected. Draft entries are not reviewable yet.
Missing-widget console warning after an upgrade past 19The widget is removed on the Odoo 20 development branch. Swap the view back to char_with_placeholder_field during migration.

To review badge widget vs the alternatives

WidgetBest forKey difference
char_with_placeholder_field_to_checkEntry-number columns that must flag posted, unreviewed recordsAdds a group-gated To review pill driven by the checked and state fields
char_with_placeholder_fieldThe same column without a review flagIdentical display, including placeholder-as-value, minus the badge
badgeShowing a status value as a colored pill on its ownRenders the field value itself as the badge instead of appending one to a char value
account_document_stateStatus fields that must explain themselves on hoverSelection-based label with an info popover fed by a message field

Use this widget when the flag belongs next to an identifying char column. The moment the status is the information itself, a selection-based badge widget is the more honest choice.

Frequently asked questions

What makes the To review badge appear in Odoo 19 journal entry lists?+
Three conditions at once: the record's checked field is loaded and exactly false, its state is posted, and the current user belongs to account.group_account_user. Core loads checked as an invisible column specifically to feed the badge.
Why don't invoicing-only users see the badge?+
The badge element carries groups="account.group_account_user", so it renders only for full accountants. Users with the lighter invoicing access see a plain number column, which is intentional: the review workflow belongs to accountants.
Is char_with_placeholder_field_to_check configurable?+
Not meaningfully. It inherits the char field's placeholder options through char_with_placeholder_field, but the badge itself, its text, color, field names and state value, is hardcoded in the template extension.
Can I reuse the widget for my own review workflow?+
Yes, if your model uses the exact field names the template reads: a boolean named checked and a state selection whose reviewable value is posted, both loaded in the view. Different names mean subclassing the template with your own condition, which is a small, clean customization.
Why does the source file name end in _to_check_to_check.js?+
The suffix was pasted twice when the file was created; the directory carries it once. It changes nothing functionally, but it is a handy trivia point when you are hunting the file, and a hint at how short-lived this component was: created in 19, deleted on the development branch.
What replaces the widget in Odoo 20?+
Nothing directly, as of the current development branch. The subclass is deleted, both lists revert to the plain char_with_placeholder_field, and the invisible checked companion columns are removed. We re-verify this page once Odoo 20 ships in September 2026.

Need review and approval flags your team actually sees?

Inline status nudges beat buried filters: badge conditions, access-group gating and companion fields have to line up exactly, as this widget shows. We build approval and review workflows inside Odoo lists and forms for versions 16 through 19.

Design my review workflow

How this page was produced

Verified by reading char_with_placeholder_field_to_check_to_check.js and its template extension in the Odoo 19.0 account module, plus the parent char_with_placeholder_field sources, and confirming both usages and the invisible checked companion fields in account_move_views.xml. The badge conditions were exercised on a clean Odoo 19 database, where the screenshot was captured. The Odoo 20 findings come from diffing the component directory and the views against the public development branch, where both are removed. Spotted a change we have not caught yet? Tell us.