The CWA is in heavy development
The CWA is still in alpha and not ready for production - some code and implementations are likely to change. If you would like to try out the CWA, please enjoy what we have provided and feel free to provide feedback, or get involved on GitHub.
DraftComponent

useCwaFormInput

Bind a single Symfony form field to a reactive value, validate on input, and control when errors are displayed.

useCwaFormInput binds a single field inside a Form component to a reactive value and handles per-field validation, error display, and value synchronisation with the shared form store.

const { value, vars, errors, valid, displayErrors, onBlur, validate, onInput } = useCwaFormInput(iri, fullName)

Parameters

ParameterTypeDescription
iriRef<string | undefined>IRI of the Form component resource
fullNamestringSymfony field full_name (e.g. contact_form[name])

Return value

PropertyTypeDescription
valueRef<any>Reactive local value — bind to your <input> with v-model
varsComputedRefFull field vars from the API (label, attr, errors, valid, etc.)
errorsComputedRef<string[]>Field-level error messages from the API
validComputedRef<boolean | null>true = valid, false = invalid, null = not yet evaluated
displayErrorsComputedRef<boolean>Whether errors should be shown — see below
onBlur() => voidCall on @blur to enable error display after the user leaves the field
validate(extraData?) => Promise<void>Trigger PATCH validation immediately
onInput() => voidDebounced (300 ms) wrapper around validate — call on @input

displayErrors

Errors should be displayed when any of the following is true:

  • The user has blurred the field (onBlur was called)
  • The field was previously valid and has since become invalid (regression)
  • The form has been submitted and failed (isSubmitAttempted is true for this IRI)

Bind it to a conditional wrapper around your error list so errors only surface at the right moment.

validate()

For PATCH forms only: sends the current field value to the form's submit endpoint via PATCH so the API can validate it and return per-field errors. The store is updated automatically, and errors / valid react accordingly.

For POST forms, validate() is a no-op — validation only happens on full submission.

Field full_name

Symfony serialises form fields using their full_name, which follows the pattern form_name[field_name] (or form_name[child][field_name] for nested fields). The value comes from vars.value.full_name in the form resource response.

Value lifecycle

  • Initialised from vars.value (the API's current value for this field)
  • Resets to the API value when iri changes (e.g. navigating between resources)
  • Synced into $cwa.forms.fieldValues so useCwaForm.submit() can read all fields at once
  • Cleared from the store on component unmount

Example

<script setup lang="ts">
const props = defineProps<{ iri: string; fullName: string }>()
const iriRef = toRef(props, 'iri')

const { value, vars, errors, displayErrors, onBlur, onInput } = useCwaFormInput(iriRef, props.fullName)
</script>

<template>
  <div>
    <label :for="props.fullName">{{ vars?.label }}</label>

    <input
      :id="props.fullName"
      v-model="value"
      v-bind="vars?.attr"
      @blur="onBlur"
      @input="onInput"
    />

    <ul v-if="displayErrors && errors.length">
      <li v-for="error in errors" :key="error" class="text-red-500">
        {{ error }}
      </li>
    </ul>
  </div>
</template>

Notes

  • Each field component should call useCwaFormInput with its own fullName — the composable registers itself in the shared store and cleans up on unmount
  • onInput is a 300 ms debounce so rapid typing doesn't flood the API with validation requests; call validate() directly if you need immediate validation
  • Extra data can be passed to validate(extraData) — it is merged into the PATCH body, useful when validation of one field depends on another's current value