react-thaizip

Forms

Submit Thai address values with browser forms or connect them to form-library state

The components generated by the CLI are regular browser form elements. They do not send or store data for you. When you provide name, the component renders hidden inputs that normal FormData and form submission can read.

Submit with a browser form

Set name="address" to render these four fields:

address-subdistrict
address-district
address-province
address-zipcode

After an address is selected, new FormData(form) has this payload shape. Area names are the selected Thai names, even when the UI is displayed in English:

{
  'address-subdistrict': 'คลองตันเหนือ',
  'address-district': 'วัฒนา',
  'address-province': 'กรุงเทพมหานคร',
  'address-zipcode': '10110',
}

This example prevents the form submission, reads FormData, and displays it on the page, so it needs no server:

Form integration

Submit the address component’s hidden fields with a regular browser form.

Blur count: 0. No address selected yet.

Submitted fields
null
Form integration

Submit the address component’s hidden fields with a regular browser form.

Province
District
Sub-district
Postal code

Blur count: 0. No address selected yet.

Submitted fields
null

Autocomplete and cascade select render the same field names. If you pass disabled, all four hidden inputs are disabled too and are omitted from FormData.

Use a form library

Keep ResolvedThaiAddress | null in your form state or library controller, then pass it back through value. For autocomplete, this controlled pattern gives validation, resets, and submission one source of truth.

const [address, setAddress] = useState<ResolvedThaiAddress | null>(null)

<ThaiAddressAutocomplete
  name="address"
  value={address}
  onValueChange={setAddress}
/>

For ThaiAddressCascadeSelect, use the form value for a complete resolved address only. The cascade manages an in-progress province/district selection internally and does not emit a resolved value until all three levels are selected. Passing value={null} clears an existing complete selection but intentionally preserves an in-progress partial selection, so form state is not the sole source of truth for that partial UI.

On a normal form reset, pass null to clear the saved complete address. If the reset must also discard an in-progress partial cascade selection, deliberately remount the cascade by incrementing a reset key:

<ThaiAddressCascadeSelect key={resetVersion} name="address" value={address} onValueChange={setAddress} />

Validation and accessibility

  • required is applied to the autocomplete input or all three cascade-select controls.
  • aria-invalid communicates an invalid state: autocomplete applies it to its input and cascade select applies it to all three triggers.
  • Autocomplete's onBlur runs when its input loses focus; cascade select's runs when the province trigger loses focus.
  • The autocomplete ref is an HTMLInputElement; the cascade-select ref is the province-trigger button, so either can be focused by your form logic.

For example, pass aria-invalid={Boolean(error)} from form validation and use ref.current?.focus() to return someone to the primary control that needs attention.

See autocomplete for free-text search, cascade select for ordered selection, and Customization for text and class slots.

On this page