sanity icon indicating copy to clipboard operation
sanity copied to clipboard

Conditional fields custom type not working

Open qucode1 opened this issue 4 years ago • 6 comments
trafficstars

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:

custom-image-standalone

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.

custom-image-hero-section

To Reproduce

Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. 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

qucode1 avatar Nov 20 '21 18:11 qucode1

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.

plsrd avatar Nov 22 '21 21:11 plsrd

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.

qucode1 avatar Nov 23 '21 13:11 qucode1

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)

qucode1 avatar Dec 01 '21 20:12 qucode1

I also have the same problem. Fields of type object are not being properly hidden with all their subfields. That was working before.

PHCCorso avatar Jan 13 '22 10:01 PHCCorso

Can confirm that the bug still exists. Tried to hide an alt-text field when a decorative boolean was true.

joaisa17 avatar May 04 '22 10:05 joaisa17

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;
            })
        }
    ]
}

joaisa17 avatar Aug 09 '22 12:08 joaisa17

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.

kmelve avatar Jan 13 '23 09:01 kmelve