decap-cms icon indicating copy to clipboard operation
decap-cms copied to clipboard

Allow users to add additional options to the select widget directly

Open josh-unwin opened this issue 5 years ago • 19 comments
trafficstars

As per the react-select module, it would be great if Netlify CMS could allow users to add additional options to the select widget directly from itself. Screenshot 2020-05-27 at 14 28 20

The difficulty here is whether this added option can be plugged into the options list in the config.yml file.

josh-unwin avatar May 27 '20 12:05 josh-unwin

@erezrokah @erquhart Interested in tackling this issue. Does this ticket cover adding new options to the relation widget as well, or should a new ticket be created for that?

My first thoughts for an implementation would be: Display a modal to add a new option to the select. The modal would contain the relations fields for the user to fill out. The modal would have Publish and Cancel buttons (you won't be able to save a draft of the relation you want to add). Once the relation you want to add is Published, it's added to the relation widget. Side note: If this option is taken, might need to resolve #1571 first before working on this, as I assume only collections that do not have editorial workflow enabled will be supported here.

Motivation/Use Case

The simplest use case where I see this being extremely useful is with tags, where you may have a tags folder collection with just a single title field.

For example, imagine you have tags and posts collections, and tags is implemented as a folder collection in config.yml. I want to be able to create new tags from a relation widget inside a post entry without having to leave the post entry. From a UX perspective, it's quite tiresome to have to click back to the dashboard, click on the tags collection, create new tag, add the tag, save, set ready status, publish, go back to dashboard, find original post entry, then finally be able to add the tag to your entry. Would be very nice to be able to just create it inline on the post entry.

Thoughts?

kwyoung11 avatar Jun 21 '20 21:06 kwyoung11

Thanks @kwyoung11, I think this would only cover the select widget for now.

Instead of changing the config.yml (which will probably trigger an unwanted CI build) the widget could support an additional allow_add flag and then save the additional options under the entry data, e.g.

options:
 selected: string | string[]
 additional: string[]

That would mean the widget would need to support persisting an object instead of the current list or string.

WDYT?

erezrokah avatar Jun 22 '20 09:06 erezrokah

Note: this issue ties into #192, which calls for making related changes in one entry from another entry - in this case adding a tag to a centralized tags data file from an entry that will reference the tag. That part of the request is a duplicate.

To echo @erezrokah, the core ability to add arbitrary values to a select, without persisting that value to any centralized, reusable set of values, should be really simple. I would even suggest that the selected/additional dichotomy may not be necessary - allow_add could just allow any value to be added.

Also wondering if we can serve the tags use case with the relation widget as it currently works, with added logic for reducing the related values list to unique values only, and allowing relation widgets to reference the current collection if that isn't already possible. That might serve the majority of tags requirements quite well.

erquhart avatar Jun 22 '20 14:06 erquhart

@kwyoung11 @erezrokah Any plans for adding this? or a workaround to implement this to my project?

AbdallahAbis avatar Apr 20 '21 17:04 AbdallahAbis

Hi @AbdallahAbis, the best way to move this forward is through a contribution.

erezrokah avatar Apr 21 '21 15:04 erezrokah

@erezrokah any guidelines for someone who wants isn't a contributor and wants to contribute? Any help.

AbdallahAbis avatar Apr 21 '21 15:04 AbdallahAbis

Hi @AbdallahAbis you can see our guide here.

The select widget code is here.

Please let me know if you have any other questions.

erezrokah avatar Apr 21 '21 16:04 erezrokah

@erezrokah Could you tell me where should those newly created options be stored?

AbdallahAbis avatar Apr 21 '21 19:04 AbdallahAbis

@erezrokah Could you tell me where should those newly created options be stored?

Hi @AbdallahAbis, well I'm not sure. See https://github.com/netlify/netlify-cms/issues/3821#issuecomment-647410593 and https://github.com/netlify/netlify-cms/issues/3821#issuecomment-647547887.

The additional options can be saved as a part of the entry. That however means they will only be available per entry and not globally.

erezrokah avatar Apr 22 '21 08:04 erezrokah

@erezrokah Why can't we extend the widget options and pass it the additional options by updating config.yaml? What do you mean by unwanted CI build

AbdallahAbis avatar Apr 22 '21 17:04 AbdallahAbis

@erezrokah Why can't we extend the widget options and pass it the additional options by updating config.yaml?

Hi @AbdallahAbis, updating the config.yml means committing it back to GitHub (either directly to the default branch or via a PR). That means a build will be triggered due to the code change and also the CMS would need to wait for the build to complete to reload the config.yml file.

erezrokah avatar Apr 25 '21 07:04 erezrokah

@erezrokah So I've thought about it and I have an idea but I don't know if it will work or not as I haven't yet tried it.

  • Let's say we have a collection of articles
  • We have a field of tags on that article which is a list widget and can be either single or multiple.

We can change the list widget to be a Creatable component when the allow_add flag is true.

The new values added will be stored in the data entry (e.g. article.tags), the issue here is that they will not be available globally to other articles.

We can mimic the way Relation widget queries for fields, and we can query for the tags field and filter those tags to be unique then show them in the tags options in different articles.

My questions is:

  • can we extend the list options when the user clicks on the field to choose an option so they can see all the queried and filtered tags? Just the way Relation widget works.

WDYT?

AbdallahAbis avatar Apr 26 '21 03:04 AbdallahAbis

  • Let's say we have a collection of articles
  • We have a field of tags on that article which is a list widget and can be either single or multiple.

We can change the list widget to be a Creatable component when the allow_add flag is true.

Hi @AbdallahAbis, do you mean a select widget here?

I'm not sure we need the relation widget. Having an allow_add field will allow users to add any value which we will save on the entry. Next time the entry is loaded any custom values saved with the entry will be available for selection.

Please let me know if that works

erezrokah avatar Apr 26 '21 09:04 erezrokah

@erezrokah

do you mean a select widget here?

Yea, sorry about that, I wrote it at about 3AM 🥴

Next time the entry is loaded any custom values saved with the entry will be available for selection.

Will those added values be available to all entries? Adding tag1 to article one, will I be able to see that tag1 on article 2?

AbdallahAbis avatar Apr 26 '21 11:04 AbdallahAbis

Will those added values be available to all entries?

No they won't.

I think I'm start to understand your suggestion. You would like to query all entries (in the same collection/all collections) and extract all values and merge them?

Please note that this can have a performance hit when dealing with many entries.

erezrokah avatar Apr 26 '21 12:04 erezrokah

@erezrokah

You would like to query all entries (in the same collection/all collections) and extract all values and merge them?

Yes, exactly.

But I don't think adding an option to an entry and having it only show at that entry is that helpful. For example a tag should be available on all entries ao the content editor can easily select it on a different entry without having to remember how did they exactly write it the first time.

AbdallahAbis avatar Apr 26 '21 12:04 AbdallahAbis

Hi @AbdallahAbis, please consider you can have multiple select widgets in multiples collections and also nested ones in lists/objects.

This means we'll have to read all entries from all collections each time we load a single entry. I think the performance hit will be too big, but I don't see any harm in testing it out.

erezrokah avatar Apr 26 '21 12:04 erezrokah

I implemented my own custom widget and I am going to add it here in case it is helpful to anybody (the widget is still in early development). My approach is different from the one proposed by @AbdallahAbis. The widget uses the page building tool to populate the select entries. An example can be seen in this demo in the Jekyll Tags (HTML) entry where the built page itself is used to populate the select widget.

Andful avatar May 04 '21 19:05 Andful

Hey,

Other people were commenting on relations widged but for a novice like me it was not very apparent what and how we could use it for the problem above. Hence, this is the solution for those seeking the functionality to add new tags by using a select element.

You need 2 collections

  1. main collection with your posts
  2. second collection with tags

Then use the relation widget to query the tags collection inside the posts collection.

image

image

The full sample:

collections:
  - name: "art"
    label: "Art"
    folder: "public/docs/portfolio"
    create: true
    slug: "{{year}}-{{month}}-{{day}}_{{slug}}"
    fields:
      - label: "Tags3"
        name: "tag3"
        widget: "relation"
        collection: "tags"
        search_fields: [ "name" ]
        value_field: "name"
        display_fields: [ "name" ]
        multiple: true
  - name: "tags"
    label: "Tag"
    folder: "public/docs/tags"
    create: true
    slug: "{{slug}}"
    fields:
      - { label: "Name", name: "name", widget: "string" }

The downside to this approach is that you have to do 2/3/4 commits depending on how many new tags you want to add to a new post. On the positive side - you don't need to integrate any plugins and get to maintain all of your tags in the CMS itself.

HAVING SAID THAT, I would still prefer if the CMS allowed us to:

  1. Add new tags to select as the author of the post suggested
  2. Load a list of tags from external collection/file i.e. source: 'selectValues.json' as an example

This would give me, personally, a better control over the select. For instance it would then be possible to generate a fresh selectValues.json file in CI pipeline . This would be a nice addition to other widgets as well if people wanted to move some of the dependencies out into separate files for whatever reason.

Also, as others suggested, it would also be nice if you could add new items to collection tags, while creating a new post so it would end up being just 1 commit.

pavlexander avatar May 29 '22 19:05 pavlexander