How to Require a Field Conditionally with Custom Validation

3 replies
Last updated: Aug 26, 2021
Hey folks, is it possible to require a field conditionally? In my case I am using the Conditional Fields feature to hide/show a reference field and I would like the reference field to be a required field but only if isSubDepartment is truthy.

export default {
  title: 'Department Type',
  name: 'deptType',
  type: 'object',

  fields: [
    {
      name: 'isSubDepartment',
      title: 'Sub-Department',
      type: 'boolean',
      initialValue: true,
      description:
        'If this option selected, you will be asked to designate the "parent" department',
    },

    {
      name: 'parentDepartment',
      title: 'Parent Department',
      type: 'reference',
      to: [{ type: 'departments' }],
      options: {
        filter: 'isSubDepartment == $isSubDepartment',
        filterParams: { isSubDepartment: false },
      },
      hidden: ({ parent }) => !parent?.isSubDepartment,
      // HOW CAN I MAKE THIS VALIDATION RULE CONDITIONAL (i.e. required only if isSubDepartment is truthy?)     
      validation: (Rule) => Rule.required(),
    },
  ],
}
AI Update

Yes, absolutely! You can make validation conditional by using the custom() validation method and checking the value of isSubDepartment through the validation context.

Here's how to modify your parentDepartment field:

{
  name: 'parentDepartment',
  title: 'Parent Department',
  type: 'reference',
  to: [{ type: 'departments' }],
  options: {
    filter: 'isSubDepartment == $isSubDepartment',
    filterParams: { isSubDepartment: false },
  },
  hidden: ({ parent }) => !parent?.isSubDepartment,
  validation: (Rule) => 
    Rule.custom((value, context) => {
      // Only require the field if isSubDepartment is truthy
      if (context.parent?.isSubDepartment && !value) {
        return 'Parent Department is required when this is a sub-department';
      }
      return true;
    }),
}

The key here is that the custom validation function receives a context parameter that includes parent, which gives you access to the sibling fields in your object. You can check context.parent?.isSubDepartment to determine whether the field should be required.

If isSubDepartment is true and the field is empty, the validation returns an error message. Otherwise, it returns true to indicate the field is valid.

This approach is much more flexible than Rule.required() because you have full programmatic control over when the requirement applies. You can also adjust the error message to be more specific to your use case, which helps guide your content editors.

I haven’t really caught up with the excitement around conditional fields yet, but… I think you could do it with a custom validation something like this:
(Rule) => Rule.custom((parentDepartment, context) => context.document.isSubDepartment && parentDepartment === undefined ? "Parent department required for sub-departments" : true)

Check out durationInMinutes example on
https://www.sanity.io/docs/validation#1d8eb8fbb695
user F
That solution works brilliantly. Thank you so much!!
Great 🎉

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.

Was this answer helpful?