Skip to content

Create dialog ignores a field's defaultValue — a required select with a default renders empty and forces a manual choice #5150

Description

@yinlianghui

Summary

A field that declares defaultValue and required: true renders in the create dialog with no value selected and a required marker, so the user is forced to pick something the system already knows. The default is served to the console; the create form just does not apply it.

Measured 2026-08-04, @objectstack/console shipped with 17.0.0-rc.1, zh-CN console, fresh database, object create dialog from an object list page.

Repro

Field declaration:

status: Field.select({
  label: 'Status',
  required: true,
  defaultValue: 'draft',
  options: [
    { label: 'Draft',            value: 'draft',    default: true },
    { label: 'Pending Approval', value: 'pending'  },
    { label: 'Approved',         value: 'approved' },
    { label: 'Rejected',         value: 'rejected' },
  ],
}),

Note both spellings are present — the option's default: true and the field's defaultValue.

The default reaches the console intact. GET /api/v1/meta/objects/crm_customer_rating:

"status": {
  "label": "Status", "type": "select", "required": true,
  "defaultValue": "draft",
  "options": [{ "label": "Draft", "value": "draft", "default": true }, "..."]
}

Expected: the create dialog opens with Draft preselected.
Actual: the select shows its placeholder (请选择 / Select…) with a required asterisk. Nothing is preselected; the form cannot be submitted until the user opens the dropdown and picks a value by hand.

The server side is fine — a create that omits the field entirely is accepted and stored as draft:

$ curl --noproxy '*' -b cookies.txt -H 'Origin: http://localhost:4001' \
    -X POST http://localhost:4001/api/v1/data/crm_customer_rating \
    -H 'Content-Type: application/json' \
    -d '{"crm_account":"...","rating_year":2026}'
{"record":{"...":"...","status":"draft"}}

So this is purely the create form not seeding its default values from the object schema.

Why it matters beyond ergonomics

For a status-like field the forced choice is not neutral — every option is one click away and some of them have side effects. In our app choosing Approved at creation time immediately publishes a grade onto the parent customer record from a scorecard with no facts entered yet. The safe value is the declared default; the UI just refuses to use it.

More generally: defaultValue + required is a normal, correct way to model "this has a sensible starting value". Right now that combination produces the worst create-form experience of any modelling choice — strictly worse than declaring no default at all.

Note

There is code in plugin-form-*.js that builds default values from the object schema —

Object.keys(l.fields).forEach(t => {
  let n = l.fields[t];
  n.defaultValue !== void 0 && (e[t] = n.defaultValue);
});

— but the object create dialog does not appear to go through it. If that is a component-wiring gap rather than a missing feature, it may be a small fix.

Workaround we shipped

We removed the field from the create form entirely (via a visibleWhen predicate keyed on the record's autonumber being empty) and let the server apply the default. That works, but it is a workaround for the form not honouring metadata it already has — and it only works because conditional visibility happens to be usable here; see #5149 for the ways it is not.

Activity

  1. yinlianghui commented on Aug 4, 2026

    @yinlianghui
    CollaboratorAuthor

    Downstream reference: this is the root cause of the second half of yinlianghui/hotcrm-heimao#68. The workaround shipped in yinlianghui/hotcrm-heimao#73 removes the field from the create form entirely and lets the server apply the default.


    Generated by Claude Code

  2. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    Contributor

    分诊:pm:queue + repo:objectui(落 objectui 不打 domain)。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Migrated to objectstack-ai/objectui#4047 under #7167 (file-at-destination ruling, maintainer 2026-08-10). Native GitHub issue transfer is not available to this session's credential, so the card was recreated at the destination; this thread stays as the authoritative history and is linked from the new card. Closing as not planned here — moved, not rejected.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions