Portal Community

How Shared Paths Work

Both controls read the same initial value on mount. When either control fires a change, the engine updates the shared value in its map and both controls re-render with the new value. The last write wins.

Quick-Pick Pattern

A common use case: a free-text input paired with a button group that lets the user quickly select common values without typing:

// Schema — two controls sharing the same binding path
{
  "controls": [
    // Button group — quick-pick shortcuts
    {
      "id":    "reason-quick-pick",
      "type":  "button-group",
      "label": "Common Reasons",
      "options": [
        { "value": "Incorrect address",   "label": "Wrong address" },
        { "value": "Duplicate entry",     "label": "Duplicate" },
        { "value": "Missing information", "label": "Incomplete" }
      ],
      "binding": {
        "source": "$json",
        "path":   "rejectionReason"
      }
    },

    // Free-text input — manual entry
    {
      "id":    "reason-text",
      "type":  "textarea",
      "label": "Rejection Reason",
      "placeholder": "Select above or type a custom reason...",
      "binding": {
        "source": "$json",
        "path":   "rejectionReason"   // ← same path
      }
    }
  ]
}

Interaction Flow

  1. Form loads: both controls read $json.rejectionReason — both show the same initial value
  2. User clicks "Duplicate" in the button group: engine.setValue('reason-quick-pick', 'Duplicate entry')
  3. Engine updates the value map; reason-text re-renders showing "Duplicate entry"
  4. User edits the textarea to "Duplicate entry (system error)": engine.setValue('reason-text', 'Duplicate entry (system error)')
  5. Engine updates the value map; button group re-renders — no button is active (custom value)
  6. On submit: values['reason-text'] === 'Duplicate entry (system error)'

Important: Values Are Keyed by Control ID

Even though both controls share the same binding path, they have different control IDs. The value map contains both keys:

// After user selects "Duplicate" from the button group:
engine.getValues() === {
  'reason-quick-pick': 'Duplicate entry',
  'reason-text':       'Duplicate entry',
}

// After user edits the textarea:
engine.getValues() === {
  'reason-quick-pick': 'Duplicate entry',       // ← NOT updated (user didn't touch it)
  'reason-text':       'Duplicate entry (system error)',   // ← updated by user
}
Submit the Control That Owns the Final Value When using the quick-pick pattern, your submit handler should read from the textarea (reason-text), not from the button group. The textarea is the "primary" control that the user edited last. Alternatively, use engine.getComputedValue() with an expression that resolves which control was last modified.