Conditionally show/hide field based on input selection

I have a component where I want users to be able to choose between inserting an image or video embed code.

Here’s my code for reference:

_inputs:
  title: 
    type: text
  text: 
    type: markdown
  media_format:
    type: select
    values: 
    - name: Image
      value: image
    - name: Video Embed
      value: video
    value_key: value  
  video: 
    type: textarea
  image:
    type: image          

How would I ensure that the video field is only displayed if video is the value selected in media_format and so on for image? Is this possible or am I spoiled by ACF and Sanity?

5 Likes

Hey Ed, thanks for reaching out here. I can help you with this.

Expression engine feature request

We are hoping to do an update to our hidden feature at some point. This will allow for better expressions like:

video: 
    type: textarea
    # Not supported yet and may look once implemented
    hidden: media_format != "video"

We refer to this internally as the expression engine project. Ella mentioned this in another post about the Documentation redesign:

Alternative solution

The expression engine is still a while away, In the meantime I suggest changing your code slightly to use optional objects. For this we can use structures on an object input.

This is what I recommend for your data structure in a video example:

title:
text:
media: 
  _type: video
  video: 

And here is the image example:

title:
text:
media: 
  _type: image
  image: 

The input config would look like this:

_inputs:
  title: 
    type: text
  text: 
    type: markdown
  media:
    type: object
    options:
      structures:
        values:
          - label: Image
            icon: image
            value:
              _type: image
              image:
          - label: Video Embed
            icon: movie
            value:
              _type: video
              video:
            _inputs:
              video:
                type: code
                options:
                  syntax: html

If you use a different key from _type in your structure be sure to checkout the id_key option in the structures reference.

Selector preview:

This gives you an interface where the editor can choose which type of media they want to add. Once they choose they get the controls specific to that option which can be configured further.

Image input preview:


Video Input preview:

I assumed that the editor was pasting html code into the video textarea. As an added bonus I changed this to a code editor with html syntax highlighting.


The last thing left is to change how you read from this structure. Instead of checking media_format you check if media is set and then what media._type is set to.

Hope this helps, I will keep you posted on updates to the expression engine feature request.

4 Likes

Expression engine, now that’s a name I haven’t heard in a while…

Thanks for the thorough explanation. I was looking into the object method and that should scratch the itch for now.

4 Likes

I was indeed extremely spoiled with ACF since I have to do this all by hand in YAML and the documentation is about as clear as mud.

Now I’m trying to translate this to a button snippet. I want content editors to be able to add a button and select the color, size, and link with multiple options (external URL, internal page, file upload). Color and size work as intended since they are select fields. The object is the tricky part:

_snippets:
  button: 
    template: eleventy_liquid_bookshop_component
    inline: false
    definitions: 
      component_name: snippets/button
      named_args: 
        - editor_key: text
        - editor_key: button_link
        - editor_key: button_color
        - editor_key: button_size
    _inputs:
      button_color: 
        type: select
        options: 
          values: 
            - name: Primary
              value: primary
            - name: Secondary
              value: secondary
          value_key: value    
      button_size: 
        type: select
        options:
          values: 
            - name: Large
              value: lg
            - name: Medium
              value: md
            - name: Small
              value: sm 
          value_key: value     
      button_link: 
        type: object
        options: 
          subtype: tabbed
          structures:
            values:
              - label: External URL
                value:
                  _type: url
                  url: ""
              - label: File
                value:
                  _type: file
                  file: ""
              - label: Page
                value:
                  _type: page
                  page: ""
      button_link.url:
        type: url
      button_link.file:
        type: file
        paths:
          uploads: assets/images/uploads
      button_link.page:
        type: select
        options:
          values: collections.all

I’m attempting to make that tabbed object for the button link so a content editor can choose between adding an external link, uploading a file, or linking to a collection page. I have all my pages set up as collections so a user can choose a blog post, page, event, program, etc.

I get an error stating: “Configuration required - The data for this snippet cannot be displayed. Review its configuration in the cloudcannon.config.* file.”