Multi-input Fields
This recipe shows how you can go about implementing an input with multiple controls.
The most common example would be range of numbers that have a min and a max control.
Quick Implementation
A simple way to do this is create a "fake" input component that displays both the controls (one for min and one for max) and the error messages. The main advantage of this approach is that you can leverage existing components, validation rules etc
You can see it action on the form with fields example
<template>
<HeadlessField :name="minName">
<template #default="min">
<HeadlessField :name="maxName">
<template #default="max">
<div class="flex gap-1 items-center">
<InputText
:id="min.id"
style="width: 100px"
v-bind="min.attrs"
v-on="min.events"
placeholder="Min"
/>
<span>-</span>
<InputText
:id="max.id"
style="width: 100px"
v-bind="max.attrs"
v-on="max.events"
placeholder="Max"
/>
</div>
<div v-if="min.error"
:id="min.attrs['aria-errormessage']"
class="text-red-500">
{{ min.error }}
</div>
<div v-else-if="max.error"
:id="max.attrs['aria-errormessage']"
class="text-red-500">
{{ max.error }}
</div>
</template>
</HeadlessField>
</template>
</HeadlessField>
</template>
<script setup>
import { HeadlessField } from '@'
import { InputText } from 'primevue'
import { useAttrs } from 'vue'
const attrs = useAttrs()
const props = defineProps({
name: {
type: String,
required: true
}
})
const minName = props.name + '.min'
const maxName = props.name + '.max'
</script>In the form you can do
<EnformaField
label="Salary"
name="salary"
inputProp="NumberRange" />Alternative Implementation
Another option for implementing this would look like this:
- You build a proper input component that works independently
- The input component does not rely on the
HeadlessFieldto interact with the form - The input component emits
onInput,onChangeorupdate:modelValueto communicate with the outside world - The component is used inside the Enforma form just like a regular
<input/>
- The input component does not rely on the
- You implement specific validation rules to validate the
minandmaxparts of the range. The validation rules might look like this:range: "required|has_min|has_max|is_range". The validator rules would behas_min- checks if the range has amincomponent that is a number and returns a "Start of the range is missing" type of messagehas_max- checks if the range has amaxcomponent that is a number and returns a "End of the range is missing" type of messageis_range- checks if themaxvalue is greater than theminvalue and returns a "End of range must be greater than the start" type of message
There are trade-offs between these options. In the second option you will have to consider the following questions: If the user fills out the min when do you show the message that the max has to be filled? Most likely when the max component is blurred, right? But if the component only passes one value to the form component how could you do that?
