AbpFormField
AbpFormField connects a label, hint and error list to one control. It does not own the value or run validators.
Wire an accessible validated field
<template>
<form @submit.prevent="submit">
<AbpFormField
v-slot="{ id, describedBy, invalid }"
label="Email"
hint="Enter an email address"
:errors="errors"
required
>
<AbpInput
:id="id"
v-model="form.controls.email.value"
type="email"
:aria-describedby="describedBy"
:invalid="invalid"
@blur="form.controls.email.markAsTouched()"
/>
</AbpFormField>
<AbpButton type="submit">Validate</AbpButton>
<AbpButton variant="secondary" class="ms-2" @click="form.reset()">Reset</AbpButton>
</form>
<output>Valid: {{ form.valid }}; dirty: {{ form.dirty }}; submitted: {{ submitted }}</output>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import {
AbpButton,
AbpFormField,
AbpInput,
useAbpForm,
useValidationMessages,
Validators,
} from '@lsw-abpvue/theme-shared';
const form = useAbpForm({
email: {
value: '',
validators: [
Validators.required({ key: 'Demo::Required', defaultValue: 'Email is required' }),
Validators.email({ key: 'Demo::Email', defaultValue: 'Enter a valid email' }),
],
},
});
const messages = useValidationMessages();
const errors = computed(() =>
form.controls.email.touched ? messages(form.controls.email.errors) : [],
);
const submitted = ref(false);
function submit(): void {
submitted.value = form.validate();
}
</script>Submit an empty email, correct it, then Reset. The example's useAbpForm owns values and validation; the field only renders the resulting messages. An explicit blur handler marks the control touched.
Slot wiring
The default slot provides id, describedBy and invalid. Bind them to the control's id, aria-describedby and invalid props. Omitting that wiring leaves a visually correct label that is not programmatically connected to its control.
for supplies a fixed id; otherwise the field creates one. Keep ids unique when repeating a field. required displays the required indication, but the actual validation rule belongs in the form. disabled describes field state; explicitly disable the child control too.
Error timing and customization
Pass already localized strings to errors. A nonempty list marks the field invalid. A common policy is to show errors after touch or submission, as demonstrated. The label, hint and errors slots customize rendering; the errors slot receives the messages.
For backend errors, use server validation. Show unmatched errors at form level so a rejected request always has visible feedback.
Props, events and slots
Types come from the public contract and defaults from the current implementation. A dash means no explicit default; optional boolean props are normally false when omitted.
Props
| Name | Type | Required | Default |
|---|---|---|---|
label | string | undefined | No | — |
for | string | undefined | No | — |
required | boolean | undefined | No | — |
hint | string | undefined | No | — |
errors | readonly string[] | undefined | No | () => [] |
disabled | boolean | undefined | No | — |
Events
No component-specific events are declared.
Slots
| Name | Context |
|---|---|
default | (context: AbpFormFieldContext) => unknown |
label | () => unknown |
hint | () => unknown |
errors | (context: { errors: readonly string[] }) => unknown |