Dynamic Nuxt Form Validation

Looking for some help/guidance with NuxtUI custom form validation. I've got most of my form all wired up to validation and working properly, but the "dynamic" pieces are still a mystery. I have a form section where the end user can create infinite "resources" as a new group of input fields. Each of those resources has specific validation rules for its respective form controls. Not sure how to wire this up and I'm not seeing anything in the documentation. Can anyone point me in the right direction, please?
7 Replies
kapa.ai
kapa.ai3w ago
Hi @deetstrab. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To address your question about dynamic form validation in NuxtUI, I can provide some guidance based on the available information in the knowledge sources. The NuxtUI Form component supports custom validation, which can be useful for your dynamic form scenario. Here's how you can approach this: 1. Custom Validation Function: You can use the validate prop on the UForm component to implement your own validation logic. This function should return an array of errors, where each error has a message and a path corresponding to the form element's name attribute. Here's an example of how you can structure your custom validation:
<script setup lang="ts">
import type { FormError } from '#ui/types'

const state = reactive({
// Your form state, including dynamic resources
})

const validate = (state: any): FormError[] => {
const errors = []
// Your custom validation logic for dynamic resources
state.resources.forEach((resource, index) => {
if (!resource.name) {
errors.push({ path: `resources[${index}].name`, message: 'Resource name is required' })
}
// Add more validation rules for each resource
})
return errors
}

async function onSubmit (event: FormSubmitEvent<any>) {
console.log(event.data)
}
</script>

<template>
<UForm :validate="validate" :state="state" @submit="onSubmit">
<!-- Your form fields, including dynamic resources -->
</UForm>
</template>
<script setup lang="ts">
import type { FormError } from '#ui/types'

const state = reactive({
// Your form state, including dynamic resources
})

const validate = (state: any): FormError[] => {
const errors = []
// Your custom validation logic for dynamic resources
state.resources.forEach((resource, index) => {
if (!resource.name) {
errors.push({ path: `resources[${index}].name`, message: 'Resource name is required' })
}
// Add more validation rules for each resource
})
return errors
}

async function onSubmit (event: FormSubmitEvent<any>) {
console.log(event.data)
}
</script>

<template>
<UForm :validate="validate" :state="state" @submit="onSubmit">
<!-- Your form fields, including dynamic resources -->
</UForm>
</template>
Custom validation (https://ui.nuxt.com/components/form#custom-validation) 2. Dynamic Form Groups: For each dynamic resource, you can create a UFormGroup with a unique name attribute. This allows you to target specific fields in your validation function.
<template>
<UForm :validate="validate" :state="state" @submit="onSubmit">
<div v-for="(resource, index) in state.resources" :key="index">
<UFormGroup :label="`Resource ${index + 1}`" :name="`resources[${index}].name`">
<UInput v-model="resource.name" />
</UFormGroup>
<!-- Add more form fields for each resource -->
</div>
</UForm>
</template>
<template>
<UForm :validate="validate" :state="state" @submit="onSubmit">
<div v-for="(resource, index) in state.resources" :key="index">
<UFormGroup :label="`Resource ${index + 1}`" :name="`resources[${index}].name`">
<UInput v-model="resource.name" />
</UFormGroup>
<!-- Add more form fields for each resource -->
</div>
</UForm>
</template>
3. Handling Errors: The Form component provides methods to handle errors dynamically. You can use these methods to set or clear errors for specific paths:
const form = ref()

// Set errors for a specific resource
form.value.setErrors([{ path: 'resources[0].name', message: 'Invalid name' }])

// Clear errors for a specific resource
form.value.clear('resources[0].name')

// Get errors for a specific resource
const errors = form.value.getErrors('resources[0].name')
const form = ref()

// Set errors for a specific resource
form.value.setErrors([{ path: 'resources[0].name', message: 'Invalid name' }])

// Clear errors for a specific resource
form.value.clear('resources[0].name')

// Get errors for a specific resource
const errors = form.value.getErrors('resources[0].name')
Form API (https://ui.nuxt.com/components/form#api) While the documentation doesn't specifically cover dynamic form validation, you can leverage these features to create a custom solution for your infinite resources scenario. Remember to adjust the validation logic as needed when resources are added or removed from your form state. If you need more specific guidance or encounter issues implementing this approach, I recommend opening a GitHub Discussion (https://github.com/nuxt/nuxt/discussions) for the Nuxt community, as they might be able to provide more tailored assistance for your particular use case. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@108353753249222656> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
NightFuries
NightFuries3w ago
The ai seemed to get the relevant portion from the docs. Is this what you were searching for?
Nuxt UI
Form - Nuxt UI
Collect and validate form data.
dwol
dwol3w ago
We have something similar but we use zod with the :schema prop on UForm. For the schema the property is an array and you use the z.array(). I know that’s not super helpful because you are using a custom validate function but we’ve been pretty happy with zod so I think it’s something worth to look into
NightFuries
NightFuries3w ago
So you have a z.array(someZodValidation) and UForm does not work with that, right? I see. Yeah, I think it is a tough one because I don't know any such form input that returns an array of items.
dwol
dwol3w ago
Sorry if I’m not being clear, using z.array does work for us.
deetstrab
deetstrabOP3w ago
sorry - had to step out. Yes, I was able to (with a bit of finesse), use the indexed-based naming. Thank you very much!
Want results from more Discord servers?
Add your server