forms(qml): prefill(values) / prefillFromJson(text) -- load a stored record into DynamicForm for editing (fixes #814) - #817
Merged
Yaraslaut merged 1 commit intoSep 25, 2026
Conversation
…record into DynamicForm for editing (fixes #814) Every prefill path wrote *control text*: CollectionView sets a `field_<name>` TextField, WizardView calls setFieldValue with text. An editing flow -- open a saved sample, read its section DTO, prefill the form, edit, submit -- had to turn each wire value into the text its control holds by hand: a {num,den,dp} into locale digits at the declared precision, an ISO instant into the display zone, a closed-set value into its valueJson, and every row of a std::vector<Row> into cell texts, the inverse of the encoder #809 added. `decodeFieldValue(field, value)` is that inverse, kind by kind, on exact digits (a Quantity's num/den are divided as digit strings, an int64 id from JsonExact.parse stays exact). `prefill(values)` replaces the whole draft from a payload object, resets unit selectors to the canonical unit, bumps `prefillRevision` so every drawn control re-seeds (a fetched Choice also re-selects when its options arrive -- before this it showed "— select —" for a retained value), re-fetches dependent Choices, and revalidates *inside* the programmaticEdit window. That last point is measured, not assumed: the first version reused withoutAutoSubmit, whose final revalidate runs after the suppression is lifted, and the round-trip case caught the ready prefilled form submitting itself. `prefillFromJson(text)` parses with JsonExact. tst_DynamicFormPrefill.qml (11 cases) asserts the round trip against previewLine for every member kind, the drawn controls and slots holding the values, de_DE and a UTC+2 display zone, a later edit, replacement semantics, a fetched Choice with an id past 2^53, and no submission. Removing the re-seed reddens 5 cases; a wrong Quantity decoder reddens 8. forms_qml_logic: 348 passed on MSVC 14.51 / Qt 6.11.1. Stacked on #809 (the rows / fieldText slot contract and itemFields it decodes into). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Yaraslaut
added a commit
that referenced
this pull request
Sep 25, 2026
…record into DynamicForm for editing (fixes #814) (#817) Every prefill path wrote *control text*: CollectionView sets a `field_<name>` TextField, WizardView calls setFieldValue with text. An editing flow -- open a saved sample, read its section DTO, prefill the form, edit, submit -- had to turn each wire value into the text its control holds by hand: a {num,den,dp} into locale digits at the declared precision, an ISO instant into the display zone, a closed-set value into its valueJson, and every row of a std::vector<Row> into cell texts, the inverse of the encoder #809 added. `decodeFieldValue(field, value)` is that inverse, kind by kind, on exact digits (a Quantity's num/den are divided as digit strings, an int64 id from JsonExact.parse stays exact). `prefill(values)` replaces the whole draft from a payload object, resets unit selectors to the canonical unit, bumps `prefillRevision` so every drawn control re-seeds (a fetched Choice also re-selects when its options arrive -- before this it showed "— select —" for a retained value), re-fetches dependent Choices, and revalidates *inside* the programmaticEdit window. That last point is measured, not assumed: the first version reused withoutAutoSubmit, whose final revalidate runs after the suppression is lifted, and the round-trip case caught the ready prefilled form submitting itself. `prefillFromJson(text)` parses with JsonExact. tst_DynamicFormPrefill.qml (11 cases) asserts the round trip against previewLine for every member kind, the drawn controls and slots holding the values, de_DE and a UTC+2 display zone, a later edit, replacement semantics, a fetched Choice with an id past 2^53, and no submission. Removing the re-seed reddens 5 cases; a wrong Quantity decoder reddens 8. forms_qml_logic: 348 passed on MSVC 14.51 / Qt 6.11.1. Stacked on #809 (the rows / fieldText slot contract and itemFields it decodes into). Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Yaraslaut
added a commit
that referenced
this pull request
Sep 25, 2026
…record into DynamicForm for editing (fixes #814) (#817) Every prefill path wrote *control text*: CollectionView sets a `field_<name>` TextField, WizardView calls setFieldValue with text. An editing flow -- open a saved sample, read its section DTO, prefill the form, edit, submit -- had to turn each wire value into the text its control holds by hand: a {num,den,dp} into locale digits at the declared precision, an ISO instant into the display zone, a closed-set value into its valueJson, and every row of a std::vector<Row> into cell texts, the inverse of the encoder #809 added. `decodeFieldValue(field, value)` is that inverse, kind by kind, on exact digits (a Quantity's num/den are divided as digit strings, an int64 id from JsonExact.parse stays exact). `prefill(values)` replaces the whole draft from a payload object, resets unit selectors to the canonical unit, bumps `prefillRevision` so every drawn control re-seeds (a fetched Choice also re-selects when its options arrive -- before this it showed "— select —" for a retained value), re-fetches dependent Choices, and revalidates *inside* the programmaticEdit window. That last point is measured, not assumed: the first version reused withoutAutoSubmit, whose final revalidate runs after the suppression is lifted, and the round-trip case caught the ready prefilled form submitting itself. `prefillFromJson(text)` parses with JsonExact. tst_DynamicFormPrefill.qml (11 cases) asserts the round trip against previewLine for every member kind, the drawn controls and slots holding the values, de_DE and a UTC+2 display zone, a later edit, replacement semantics, a fetched Choice with an id past 2^53, and no submission. Removing the re-seed reddens 5 cases; a wrong Quantity decoder reddens 8. forms_qml_logic: 348 passed on MSVC 14.51 / Qt 6.11.1. Stacked on #809 (the rows / fieldText slot contract and itemFields it decodes into). Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Yaraslaut
added a commit
that referenced
this pull request
Sep 25, 2026
…record into DynamicForm for editing (fixes #814) (#817) Every prefill path wrote *control text*: CollectionView sets a `field_<name>` TextField, WizardView calls setFieldValue with text. An editing flow -- open a saved sample, read its section DTO, prefill the form, edit, submit -- had to turn each wire value into the text its control holds by hand: a {num,den,dp} into locale digits at the declared precision, an ISO instant into the display zone, a closed-set value into its valueJson, and every row of a std::vector<Row> into cell texts, the inverse of the encoder #809 added. `decodeFieldValue(field, value)` is that inverse, kind by kind, on exact digits (a Quantity's num/den are divided as digit strings, an int64 id from JsonExact.parse stays exact). `prefill(values)` replaces the whole draft from a payload object, resets unit selectors to the canonical unit, bumps `prefillRevision` so every drawn control re-seeds (a fetched Choice also re-selects when its options arrive -- before this it showed "— select —" for a retained value), re-fetches dependent Choices, and revalidates *inside* the programmaticEdit window. That last point is measured, not assumed: the first version reused withoutAutoSubmit, whose final revalidate runs after the suppression is lifted, and the round-trip case caught the ready prefilled form submitting itself. `prefillFromJson(text)` parses with JsonExact. tst_DynamicFormPrefill.qml (11 cases) asserts the round trip against previewLine for every member kind, the drawn controls and slots holding the values, de_DE and a UTC+2 display zone, a later edit, replacement semantics, a fetched Choice with an id past 2^53, and no submission. Removing the re-seed reddens 5 cases; a wrong Quantity decoder reddens 8. forms_qml_logic: 348 passed on MSVC 14.51 / Qt 6.11.1. Stacked on #809 (the rows / fieldText slot contract and itemFields it decodes into). Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Yaraslaut
added a commit
that referenced
this pull request
Sep 25, 2026
…orm encodes its rows (#809) * forms(qml): a host slot can draw a std::vector<Row> member, and the form encodes its rows A collection of objects has no built-in control: the comma-separated array control encodes strings, so DynamicForm reports the member unrepresentable and a form that must carry it never becomes ready. That was right for the built-in controls, and it left a host with nowhere to go -- registering a grid slot for the member changed nothing, because the slot could only hand `setValue` a text the array encoder then split on commas, and the slot was never told what the row type's members are. When a registered slot claims a top-level `std::vector<Row>` member: - `fields` describes the row type with the same descriptor builder the action uses (`describeObject`, depth-limited to one level so a self-referential row type cannot loop) and puts it on the field as `itemFields`: label, unit, decimals, readOnly, required and the kind flags, in x-order order -- the grid's columns. `isObjectArray` and `claimedBySlot` say which case the descriptor is. - `unrepresentable` is "" for it, because an encoding now exists. - The slot writes rows as `{member: cellText}` objects, where a cell holds what that member's built-in control would hold. `encodeObjectArray` encodes every cell with `encodeFieldText` -- `fieldJsonLiteral`'s body, lifted to take an explicit text and unit index -- so a `Quantity` cell is an exact {num,den,dp}, an over-precise one is refused rather than rounded, a blank optional cell is omitted and a blank required one keeps the form unready. Slots also gain four optional members, each assigned only when the slot declares it, so every existing slot is untouched: `fieldText` (a binding to the retained text -- until now a slot never learned a value it had not written itself, so prefill, `resetFields()` and a tab rebuild all left it stale), `rows`, `setRows(rows)` and `form`. With `fieldText`, CollectionView's row prefill reaches a slot-overridden scalar field too, which views.md listed as a limitation. Nothing changes without a slot: tst_DynamicFormNestedAggregate.qml is untouched and green. The new tst_DynamicFormObjectArraySlot.qml (18 cases) asserts submitted bodies; replacing the cell encoder with plain string quoting reddens 3 of them. forms_qml_logic: 335 passed on MSVC 14.51 / Qt 6.11.1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(forms): the object-array suite has 18 cases, not 17 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * forms(qml): prefill(values) / prefillFromJson(text) -- load a stored record into DynamicForm for editing (fixes #814) (#817) Every prefill path wrote *control text*: CollectionView sets a `field_<name>` TextField, WizardView calls setFieldValue with text. An editing flow -- open a saved sample, read its section DTO, prefill the form, edit, submit -- had to turn each wire value into the text its control holds by hand: a {num,den,dp} into locale digits at the declared precision, an ISO instant into the display zone, a closed-set value into its valueJson, and every row of a std::vector<Row> into cell texts, the inverse of the encoder #809 added. `decodeFieldValue(field, value)` is that inverse, kind by kind, on exact digits (a Quantity's num/den are divided as digit strings, an int64 id from JsonExact.parse stays exact). `prefill(values)` replaces the whole draft from a payload object, resets unit selectors to the canonical unit, bumps `prefillRevision` so every drawn control re-seeds (a fetched Choice also re-selects when its options arrive -- before this it showed "— select —" for a retained value), re-fetches dependent Choices, and revalidates *inside* the programmaticEdit window. That last point is measured, not assumed: the first version reused withoutAutoSubmit, whose final revalidate runs after the suppression is lifted, and the round-trip case caught the ready prefilled form submitting itself. `prefillFromJson(text)` parses with JsonExact. tst_DynamicFormPrefill.qml (11 cases) asserts the round trip against previewLine for every member kind, the drawn controls and slots holding the values, de_DE and a UTC+2 display zone, a later edit, replacement semantics, a fetched Choice with an id past 2^53, and no submission. Removing the re-seed reddens 5 cases; a wrong Quantity decoder reddens 8. forms_qml_logic: 348 passed on MSVC 14.51 / Qt 6.11.1. Stacked on #809 (the rows / fieldText slot contract and itemFields it decodes into). Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * forms(qml): a slot registered by kind claims an object-array collection too slotClaims() is the delegate's own slot resolution, but it passed five arguments while the delegate passes the kind as well, so a grid registered with SlotRegistry.byKind("objectArray", ...) was drawn while the form kept the collection unrepresentable and never encoded its rows. The kind is now computed once per descriptor and handed to both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4eif7wQNNhSkHUKYqq5Xq * forms(qml): prefill() suppresses auto-submit through withoutAutoSubmit The helper now revalidates inside its suppression window, so the hand-rolled copy in prefill() and its comment explaining why it avoided the helper no longer describe anything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4eif7wQNNhSkHUKYqq5Xq --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #814.⚠️ Stacked on #809 (base branch
feature/forms-object-array-slot): it decodes into #809'sitemFields/rows/fieldTextslot contract. Retarget tomasteronce #809 merges.Editing flow: open saved record → read its DTO →
form.prefillFromJson(json)→ user edits → submit.Quantity{num,den,dp}→ exact digits at canonicalx-decimalPlaces, display locale; unit selector reset to canonicalx-displayDecimalswhen declared (#808), never roundedChoice/ enumvalueJson(ids past 2^53 exact viaJsonExact)TimestampdisplayOffsetMinutesstd::vector<Row>{member: cellText}, each decoded by the row member's descriptordecodeFieldValue(field, value)is the inverse ofencodeFieldText;prefill(values)replaces the whole draft, re-seeds every drawn control (prefillRevision) and slot (fieldText,rows), re-selects a fetchedChoicewhen its options arrive (previously it showed "— select —" for a retained value), re-fetches dependent Choices.programmaticEdit. The first version reusedwithoutAutoSubmitand the round-trip test caught the prefilled form submitting itself — see the filed follow-up about the same pattern on tab rebuilds.docs/spec/forms/forms.md, new "Prefill — loading a stored payload for editing".Tests (MSVC 14.51, Qt 6.11.1): new
tst_DynamicFormPrefill.qml(11 cases, round trip vspreviewLinefor every kind, de_DE, UTC+2, slots, fetched Choice, no submit). Removing the re-seed reddens 5; a wrong Quantity decoder reddens 8.forms_qml_logic348 passed.🤖 Generated with Claude Code