Dynamic validation for optional object fields in Sanity.io
4 replies
Last updated: Oct 29, 2021
P
I've got an object with a bunch of fields with validation. The object is optional (using the
hidden()function). Is there a way to only validate fields if the object they're part of is not hidden?
Oct 22, 2021, 3:21 PM
P
Ah right, but I don't know what the conditions will be, because this object can be used in a lot of different documents (it's a link type object, with label, internal en external field). Any way to get the actual hidden value used for the parent?
Oct 23, 2021, 10:48 AM
What does your object schema look like? I'll play around with it to see if I can make the validation rule dynamic based off of an unknown parent's visibility.
Oct 25, 2021, 4:46 PM
P
Cool, this is the
It's used another object, chapter:
linkobject:
export const link = {
title: 'Link',
name: 'link',
type: 'object',
fields: [
{
title: 'Type',
name: 'type',
type: 'string',
initialValue: 'internal',
options: {
layout: 'radio',
direction: 'horizontal',
list: [
{ value: 'internal', title: `Internal` },
{ value: 'external', title: `External` }
]
}
},
{
title: 'Tekst',
name: 'text',
type: 'string',
validation: Rule => Rule.required().error('This field is required')
},
{
title: 'Url',
name: 'internalLink',
type: 'internalLink',
hidden: ({ parent }) => parent?.type !== 'internal',
validation: requiredIf(({ parent }) => parent?.type === 'internal')
},
{
title: 'Url',
name: 'externalLink',
type: 'externalLink',
hidden: ({ parent }) => parent?.type !== 'external',
validation: requiredIf(({ parent }) => parent?.type === 'external')
}
]
}
function requiredIf(fn) {
return Rule => Rule.custom((value, context) => (!value && fn(context)) ? 'This field is required' : true).error()
}export const chapter = {
title: 'Hoofdstuk',
name: 'chapter',
type: 'object',
fields: [
{
title: 'Type',
name: 'chapterType',
type: 'string',
options: {
list: [
{ title: 'Afbeelding', value: 'image' },
{ title: 'Afbeelding met tekst', value: 'imageWithText' },
{ title: 'Video', value: 'video' },
{ title: 'Geanimeerde quote', value: 'animatedQuote' },
{ title: '360 Afbeelding', value: '360' },
{ title: 'Link', value: 'link' },
]
},
validation: Rule => Rule.required().error('Dit veld is verplicht')
},
{
title: 'Link',
name: 'link',
type: 'link',
hidden: ({ parent }) => !['link'].includes(parent?.chapterType),
validation: Rule => Rule.custom((value, context) => (
!value && context.parent?.chapterType === 'chapterWithLink'
? 'Dit veld is verplicht'
: true
).error()
}
]
}Oct 25, 2021, 7:48 PM
P
Not really possible, right?
Oct 29, 2021, 8:01 AM
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
