sanity
sanity copied to clipboard
Conditional fields custom type not working
Describe the bug
I created a custom document schema "customImage", with conditional fields like "guitar" that is hidden if a "isGuitar" boolean field is false.
export default {
name: "customImage",
title: "Custom image",
type: "document",
fields: [
{
name: "image",
title: "Image",
type: "image",
options: {
hotspot: true,
},
validation: (Rule) => Rule.required(),
},
{
name: "alt",
title: "alt",
description: "What is shown in the image?",
type: "string",
validation: (Rule) => Rule.required(),
},
{
name: "href",
title: "href",
description: "Image URL",
type: "string",
},
{
name: "target",
title: "link target",
type: "string",
options: {
list: ["_blank", "_self", "_parent", "_top"],
},
initialValue: "_self",
hidden: ({ document }) => !document.href,
},
{
name: "isGuitar",
title: "Add guitar info",
type: "boolean",
initialValue: false,
},
{
name: "guitar",
title: "Guitar",
type: "reference",
to: [{ type: "guitar" }],
validation: (Rule) => Rule.custom(((guitar, context) => {
if (!context.document.isGuitar && typeof guitar === "undefined") return true;
return context.document.isGuitar && guitar && true || 'Please select a guitar';
})),
hidden: ({ document }) => !document.isGuitar,
},
{
name: "guitarSpecs",
title: "Guitar Specs",
type: "object",
fields: [
{
name: "type",
title: "Guitar Type",
type: "string",
options: {
list: ["Guitar", "Bass Guitar"],
},
initialValue: 'Guitar',
validation: (Rule) => Rule.required(),
},
],
hidden: ({ document }) => !document.isGuitar,
},
],
};
This works perfectly fine on it's own:
Then I used customImage in a "heroSection" document schema.
export default {
name: "heroSection",
title: "Hero section",
type: "document",
fields: [
{
name: "heroImage",
title: "Hero Image",
type: "customImage",
},
{
name: "heroHeadline",
title: "Hero Headline",
type: "string",
},
{
name: "heroSubHeadline",
title: "Hero Sub-Headline",
type: "string",
},
{
name: "heroCTAText",
title: "Hero CTA Text",
type: "string",
},
{
name: "heroCTALink",
title: "Hero CTA Link",
type: "string",
},
],
};
Unfortunately this does not react to the change and keeps the conditional fields hidden.
I tried using href as the trigger to test a different a string instead of a boolean, but that didn't help.
To Reproduce
Steps to reproduce the behavior:
- Go to '...'
- Click on '....'
- Scroll down to '....'
- See error
Expected behavior
The hidden fields should show up after a change of the boolean field "isGuitar".
Which versions of Sanity are you using?
@sanity/cli 2.22.0 (up to date)
@sanity/base 2.22.0 (up to date)
@sanity/components 2.14.0 (up to date)
@sanity/core 2.22.0 (up to date)
@sanity/default-layout 2.22.0 (up to date)
@sanity/default-login 2.22.0 (up to date)
@sanity/desk-tool 2.22.2 (up to date)
@sanity/production-preview 2.15.0 (up to date)
@sanity/vision 2.22.0 (up to date)
Run sanity versions in the terminal and copy-paste the result here.
What operating system are you using?
Which versions of Node.js / npm are you running?
8.1.3
v16.13.0
This is likely happening because customImage is a document and cannot be embedded inside of another document in this way. You would have to change the field to a reference to a customImage. Note, though: you cannot currently edit references in place inside of the Studio. You would need to create the customImage document then add the reference in your hero.
Interesting. With that in mind, I changed the type to object instead of document, but the behaviour remains the same. Everthing except the conditional fields seems to work to work in both cases though, so I still believe that this is a bug.
I guess I will stick to the reference solution for now and hopefully there will be a way to create references directly soon.
I just learned that I don't really need a customImage type and can extend the image type with custom fields instead. The issue with conditional fields still remains though. They're not reactive in nested models.
@sanity/cli 2.22.3 (up to date)
@sanity/base 2.22.3 (up to date)
@sanity/components 2.14.0 (up to date)
@sanity/core 2.22.3 (up to date)
@sanity/default-layout 2.22.3 (up to date)
@sanity/default-login 2.22.3 (up to date)
@sanity/desk-tool 2.22.3 (up to date)
@sanity/production-preview 2.15.0 (up to date)
@sanity/vision 2.22.3 (up to date)
I also have the same problem. Fields of type object are not being properly hidden with all their subfields. That was working before.
Can confirm that the bug still exists. Tried to hide an alt-text field when a decorative boolean was true.
Fix (use .parent)
Been a while, but I think I finally figured it out! When you're running the hidden callback, instead of using { document } to read the values, use { parent }.
Check this link
The following example works within a document:
export default {
name: 'img',
type: 'object',
title: 'Bilde',
fields: [
{
name: 'type',
type: 'string',
title: 'Bildetype',
initialValue: 'file',
options: {
layout: 'radio',
list: [
{ title: 'Bildefil', value: 'file' },
{ title: 'URL', value: 'url' }
]
},
validation: r => r.required()
},
{
name: 'url',
type: 'url',
title: 'URL',
description: 'Direkte URL til bildet.',
hidden: ({ parent }) => parent?.type !== 'url',
validation: r => r.custom((value, { parent }) => {
if (parent?.type === 'url' && !value) return 'Feltet må fylles ut.';
return true;
})
},
{
name: 'file',
type: 'image',
title: 'Bildefil',
hidden: ({ parent }) => parent?.type !== 'file',
validation: r => r.custom((value, { parent }) => {
if (parent?.type === 'file' && !value) return 'Fil mangler.';
return true;
})
}
]
}
Hi!
We are currently working on improving our workflows and follow-up on our open GitHub repository. In that work, we have decided to close most issues older than the release of Sanity Studio v3.
We value your feedback, so if this issue is still important to you and relevant for Sanity Studio v3, please search for relevant open issues. If you can’t find any, open a new one and link to relevant comments in this thread. For questions about how to do something, please post them in the slack community.