sveltia / sveltia-cms

Alternative to Netlify/Decap CMS. Fast, lightweight, Git-based headless CMS. Modern UX, first-class i18n support, open source & free. Made with Svelte.
MIT License
862 stars 43 forks source link

Conditional fields #139

Closed CarloBu closed 4 months ago

CarloBu commented 4 months ago

I can't find the option to make Conditional fields based of the boolean status. The idea is to make field visibility conditional, based on other fields' values. maybe it's here, but I can't find it.

by example:

the idea that the News Description field would be visible only when isNews boolean is true. that would give a good UX for the client to see only fields that are required for the situation. In this case, the news field would be shown if the project is news worthy, image image

kyoshino commented 4 months ago

I think this is relevant:

Sveltia CMS has already solved this problem by supporting variable types for the Object widget, not only for the List widget. I don’t have a detailed document yet, but you can use the same types option to have conditional fields. Check it out!

CarloBu commented 4 months ago

Yes, I'm familiar with this, I'm using this feature already for other collections. You are right, that this is already working from another way. I just thought the boolean + condition field would be a more intuitive solution for this particular case when I need a clear on-off state. this is the solution with the variable types. I just need to inform the client not to generate more than one news field and the problem is solved.

    fields:
      - label: 'Is it News?'
        name: 'isNews'
        required: false
        widget: 'list'
        types:
          - label: 'News Description'
            name: 'carousel'
            widget: string
            fields:
              - {label: News Description, name: newsDescription, widget: string, required: false}

https://github.com/sveltia/sveltia-cms/assets/145860771/d148c689-8a3e-42c2-aaa7-3829fa9f0c36

kyoshino commented 4 months ago

For the variable object types, you can add only one field. Actually in your case, you can just use required: false with widget: object instead of variable types:

    fields:
      - label: 'Is it News?'
        name: 'isNews'
        required: false
        widget: object
        fields:
          - label: 'News Description'
            name: 'carousel'
            widget: string
            fields:
              - {label: News Description, name: newsDescription, widget: string, required: false}

The UI will look like:

image image

This cannot be done with Netlify/Decap CMS πŸ˜†

CarloBu commented 4 months ago

oh, this is much better, thanks!

kyoshino commented 4 months ago

And yeah, as you said, a checkbox may be more intuitive here. I can change the UI πŸ™‚

CarloBu commented 4 months ago

yes, but if it's only not hard to implement for you.

I guess it could be simple ternary operator to the string widget and could look like:

fields:
  - label: Is it News?
    name: isNews
    widget: boolean   <- or checkbox
    default: true
    required: false}
  - label: News Description
    name: newsDescription
    visibleIf: 'isNews'         <- maybe like this, or name it displayCondition?
    widget: string}
CarloBu commented 4 months ago

wait, you mentioned checkboxes, are checkboxes possible for relation widget? image

I went to the sveltia and decapcms issues and found only mention custom tag widget that is not supported at sveltia. I made that the client can build and modify categories list through reference content collection schema, and at current I can only let to select only one item through radio buttons. If it's possible to convert this field to checkboxes to get the array, please give me a hint. fields:

image

kyoshino commented 4 months ago

You can get checkboxes with widget: relation + multiple: true.

CarloBu commented 4 months ago

hehe, lol, that's unexpected: image it works like a charm! I double checked now, and I still didn't find about "multiple: true" in the sveltiacms or decap readme. You need proper documentation about advanced fields. :) I will collect these cool options that I will find and prepare these for the template, 100% sure very few people know about these powerful options.

kyoshino commented 4 months ago

I think the Decap Relation widget doc mentions the multiple option πŸ™‚ The checkbox UI is only with Sveltia πŸ˜†

I just shipped v0.26.2 to use a checkbox for optional (required: false) objects. I’ll work on conditional fields sometime later.

image
CarloBu commented 4 months ago

I care a lot about the client's UX, and you make me happy! thanks!

this is better now than I expected!

CarloBu commented 3 months ago

Hey, @kyoshino I think I found the bug in the checkbox for optional objects when there is a nested list, it generates a duplicate in the second language. for a single language, it works fine.

this is a strip-down config setup to replicate the bug behaviour.

i18n:
    structure: multiple_folders
    locales:
        - lt
        - en
    default_locale: lt
    canonical_slug:
      key: defaultLocaleVersion
      value: 'lt/{{slug}}'
slug:
  encoding: "ascii"
  clean_accents: true
  sanitize_replacement: "-"
collections:
  - name: Test
    label: testPage
    folder: src/content/test
    create: true
    i18n: duplicate
    format: yml
    extension: yaml
    fields:
      - label: 'Test Field'
        name: 'testField'
        required: false
        widget: object
        i18n: duplicate
        fields:
          - label: 'Nested test field list'
            name: 'nestedTestFieldList'
            widget: list
            i18n: duplicate
            fields:
              - {label: Title, name: title, widget: string, i18n: true}

https://github.com/sveltia/sveltia-cms/assets/145860771/bd6bdc6c-6e51-4c77-a534-d4f6304534e5

CarloBu commented 3 months ago

my requested optional field feature come to bite me :)

edit edit: I think I finally got it :) When creating or modifying an entry in Sveltia CMS, if I click on a checkbox and then uncheck it, Sveltia does not register the unchecked field as null. The same issue occurs with populated data in a checked field that is then unchecked. Sveltia only registers a null value if the checkbox field is untouched. and it does not matter what the setup is

edit: It appears that whether null gets registered in the YAML file or not is random. In a long collection setup, if I change a seemingly unrelated field, Sveltia saves the YAML file without registering null for an unchecked field. I couldn't pinpoint what makes Sveltia fail to register null for an unchecked field. Therefore, my best bet would be to create a helper function to ensure either null or the actual value gets saved.

I found another strange behavior with the setup below. if the title has i18n true: I get the testField null the yaml output:

title: sample
testField: null

setup:

collections:
  - name: Test
    label: testPage
    folder: src/content/test
    create: true
    i18n: duplicate
    format: yml
    extension: yaml
    fields:
      - {label: Title, name: title, widget: string, i18n: true}   <---   i18n: true
      - label: 'Test Field'
        name: 'testField'
        required: false
        widget: object
        i18n: duplicate
        fields:
          - label: 'Nested test field list'
            name: 'nestedTestFieldList'
            widget: list
            i18n: duplicate
            fields:
              - {label: Title, name: title, widget: string, i18n: true}

but when the title has i18n duplicate, I get the testField unregistered the yaml output:

title: sample

setup:

collections:
  - name: Test
    label: testPage
    folder: src/content/test
    create: true
    i18n: duplicate
    format: yml
    extension: yaml
    fields:
      - {label: Title, name: title, widget: string, i18n: duplicate} <---  i18n: duplicate
      - label: 'Test Field'
        name: 'testField'
        required: false
        widget: object
        i18n: duplicate
        fields:
          - label: 'Nested test field list'
            name: 'nestedTestFieldList'
            widget: list
            i18n: duplicate
            fields:
              - {label: Title, name: title, widget: string, i18n: true}

I would like to get null value when the checkbox is not selected.

kyoshino commented 3 months ago

Will check.

kyoshino commented 3 months ago

The fix shipped with v0.35.0 🚒

CarloBu commented 3 months ago

super, thank you very much! Will check how it works asap