Open ghost opened 6 years ago
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?
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.
Continuing discussion from https://github.com/netlify/netlify-cms/issues/1280#issuecomment-384455171 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!
Can you provide some content/config examples of what you're currently doing and what you'd like to do?
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.)
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.
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.
+1
- 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.