Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to Enable input field only if a checkbox is checked #1267

Open
ghost opened this issue Apr 14, 2018 · 8 comments
Open

Option to Enable input field only if a checkbox is checked #1267

ghost opened this issue Apr 14, 2018 · 8 comments

Comments

@ghost
Copy link

ghost commented Apr 14, 2018

- Do you want to request a feature or report a bug?
Feature

- What is the expected behavior?
I will start with an example so that this is better understood

whitelist:
status: false
type:
start-date:
end-date:

In the code above, I want the user to only fill in the type and date fields if they change the status to true, So what i am looking for is a way to set a checkbox widget that controls input fields and makes them available when clicked on.

Another example would be a typical 'Others' Input box that becomes available when the user checks the 'others' checkbox.

@erquhart
Copy link
Contributor

erquhart commented Apr 16, 2018

This may require the same kind of dot notation field name parsing as #595, so nested fields can be referenced. Rather than being checkbox specific, what about basing a field's visibility on the value of another field (which could be a boolean/checkbox)? You could base it on the other field simply having a truthy value, or provide a specific value to look for.

Thoughts anyone?

@ghost
Copy link
Author

ghost commented Apr 17, 2018

Yes, the core idea is like how you said. When one field is set to true its dependent fields become active for user input. Implementing this will reduce a lot of clutter in the UI and give the user a better UX experience.

@ghost ghost mentioned this issue Apr 20, 2018
10 tasks
@mbrookes
Copy link

mbrookes commented Apr 26, 2018

Continuing discussion from #1280 (comment) here to avoid further cluttering the CMS 2.0 issue. (Happy to go back and delete the follow-up comments from there! 😅)

If you're saying a select widget essentially determines how the relation widget is configured (e.g. which collection it points to),

I was using select / relation interchangeably, as this may be something you want predefined in the configuration as selects, or it may be that you want to be able to edit the options available through the CMS itself by making them editable collections.

{As] an extension of #1267. [...] you'd set up a few different relation widgets and show them based on the value of the select widget.

That would be one way to do it, sure. It would mean that the top-level selection would have to be a fixed set of predefined values ("News", "Business", "Sport" etc.), but the secondary selection could be a set of editable collections.

I'd settle for that if it's the simplest to implement, as an extension of this issue, but it would be interesting to think about making the top-level a relation to a collection of collections!

@erquhart
Copy link
Contributor

Can you provide some content/config examples of what you're currently doing and what you'd like to do?

@mbrookes
Copy link

mbrookes commented Apr 27, 2018

Okay, here's one possible config. In this example, the section is a fixed list, the subsection is a collection.

collections:
  - name: "posts"
    label: "Posts"
    folder: "posts"
    create: true
    slug: "{{slug}}"
    fields:
      - {name: "date", widget: "datetime", hidden: true}
      - {label: "Section", name: "section", widget: "select", options: ["news", "reviews", "interviews", "blog"]}
    - {
        label: "Subsection",
        name: "subsection",
        widget: "relation",
        collection: "subsections",
        searchFields: ["title"],
        valueField: "title",
        filterField: "section" # Only subsections whose section matches the selection above are shown.
      }
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Subtitle", name: "subtitle", widget: "string"}
      - {label: "Body", name: "body", widget: "markdown"}
      - {label: "Tags", name: "tags", widget: "list"}

  - name: "subsections"
    label: "Subsections"
    folder: "subsections"
    create: true
    slug: "{{slug}}"
    fields:
      - {label: "Section", name: "section", widget: "select", options: ["news", "reviews", "interviews", "blog"]}
      - {label: "Subsection name", name: "title", widget: "string"}

The Posts subsection relation is filtered to those members of the subsection collection whose section matches the section chosen in the Posts section select. Ideally the subsection widget would be disabled until a section is selected.

(The Posts date field is an aspirational config for a datetime widget that can be hidden.)

@mbrookes
Copy link

mbrookes commented Apr 27, 2018

Here's one based on both section and subsection being collections:

collections:
  - name: "posts"
    label: "Posts"
    folder: "posts"
    create: true
    slug: "{{slug}}"
    fields:
      - {name: "date", widget: "datetime", hidden: true}
    - {
        label: "Section",
        name: "section",
        widget: "relation",
        collection: "sections",
        searchFields: ["title"],
        valueField: "title",
      }
    - {
        label: "Subsection",
        name: "subsection",
        widget: "relation",
        collection: "subsections",
        searchFields: ["title"],
        valueField: "slug",
        filterField: "section"
      }
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Subtitle", name: "subtitle", widget: "string"}
      - {label: "Body", name: "body", widget: "markdown"}
      - {label: "Tags", name: "tags", widget: "list"}

  - name: "sections"
    label: "Sections"
    folder: "sections"
    create: true
    slug: "{{slug}}"
    fields:
      - {label: "Section name", name: "title", widget: "string"}

  - name: "subsections"
    label: "Subsections"
    folder: "subsections"
    create: true
    slug: "{{slug}}"
    fields:
      - {
          label: "Section",
          name: "section",
          widget: "relation",
          collection: "sections",
          searchFields: ["title"],
          valueField: "title"
        }
      - {label: "Subsection name", name: "title", widget: "string"}

This would work the same way, but both the sections and subsections are configurable by virtue of being collections.

@turijs
Copy link

turijs commented Mar 7, 2019

I would also be a big fan of this feature. One use case that I have in mind is being able to change the available fields based on the chosen "layout" for a page (I am working on a Hugo site). For instance, a gallery layout would need a field for choosing images, a 2-column layout would need a second text area, etc. Right now the only way to acheive this (that I can see) would be to put all these page types into separate collections, which isn't necessarily a logical grouping for the site...or leave all fields visible at all times, which isn't great from a UX perspective.

A few thoughts on how the API could work:
Simple:

fields:
  - name: foo
    widget: string
    visible_when:
      field: bar
      compare: '='
      value: 'some val'

More complex conditions:

fields:
  - name: foo
    widget: string
    visible_when:
      and:
        - field: bar
          compare: '='
          value: 'some val'
        - field: baz
          compare: '!='
          value: 1
        - or:
            - field: bar1
              compare: '<'
              value: 100
            - field: baz2
              compare: 'in'
              value: ['red', 'green']

This would allow for an arbitrary level of complexity without introducing too much specialized syntax as in #1894.

Also agree with @erquhart's point about notation for accessing nested fields. However, simple dot notation may not be sufficient, as I can imagine scenarios where it would be useful to be able to reference a field higher in the tree without specifying an 'absolute' path. For example:

fields:
  - name: galleries
    widget: list
    fields:
      - name: name
        widget: string
      - name: show_captions
        widget: boolean
      - name: images
        widget: list
        fields: 
          - name: image
            widget: image
          - name: caption
            widget: string
            visible_when:
              field: '../show_captions' # or a better syntax...
              compare: '='
              value: true

In this case a top-down field reference wouldn't make sense due to the dynamic nature of lists.

@josejuanmartinez
Copy link

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants