Skip to content

Field-bound @ SAY GET: READ writes the record; lookup pickers in forms #59

Description

@DDecoene

Part of the v1.3.0 lookup feature. Design: docs/superpowers/specs/2026-07-10-lookup-columns-design.md (on release/v1.3.0). Builds on the LOOKUP qualifier issue.

dBASE III's actual form model: @ 5,5 SAY "Name: " GET NAME edits the current record's field and READ writes it back — no memory-variable round trip. A field-bound GET whose column declares a LOOKUP renders as a dropdown, which is how the lookup reaches forms with a single declaration site.

Scope

  • doAtSayGet resolves the GET name against the active table's columns; fields shadow memory variables (dBASE precedent; README documents the behavior change — demos audited, every GET uses m_/choice/pause)
  • FormField gains target (var | field), value (prefill), options? — options via LookupResolver
  • At READ each field-bound GET captures its alias + current-record rowid (fetchCurrentRow path); form-submit writes by rowid, exactly like grid-edit
  • form-submit: branch on target; validate ALL (declared type + lookup membership) before writing ANY; targets come from the Session-retained field list, never the client message
  • New form-error server message (offending fields + reasons); client keeps the form open and outlines them
  • FormLayout renders <select> when options are present
  • Field-bound GET with no current record: ** Error: GET <field>: no current record

Tests

  • tests/GridMessages.test.ts-style protocol coverage for the new form-submit branches + form-error, including a forged form-submit naming a column the form never offered
  • Playwright: form picker end-to-end (select rendered, chosen value written to the record)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions