Choices icon indicating copy to clipboard operation
Choices copied to clipboard

Custom attributes striped from select options

Open DieterGribnitz opened this issue 5 years ago • 6 comments

I have a select list that requires custom data attributes to be read from the selected option on change. If an item is selected a function runs using the custom option data. If I apply the lib to a select list all options are striped out and all data attributes are removed. Is there a way to keep the data attributes intact on the options? If not, can you point me to where the option in being constructed?

Thanks.

DieterGribnitz avatar Nov 04 '19 11:11 DieterGribnitz

@DieterGribnitz there is no way to keep them with the current version of Choices, but you can recreate them by overriding option property on callbackOnTemplateCreate

tinovyatkin avatar Nov 04 '19 12:11 tinovyatkin

Thanks I will give it a try.

DieterGribnitz avatar Nov 04 '19 12:11 DieterGribnitz

Is there still no easy way to do this ? Thanks.

MatthieuWinalist avatar May 14 '21 08:05 MatthieuWinalist

We ran into this issue and got an "easy" fix :

new Choices(select, {
            callbackOnCreateTemplates: function () {
                return {
                    option: ({ label, value, customProperties, active, disabled, }: Item) => {
                        const opt: HTMLOptionElement = Choices.defaults.templates.option.call(
                            this,
                            { label, value, customProperties, active, disabled }
                        );

                        // We get the original <option> from choicejs
                        const originalOption: HTMLOptionElement = this._presetOptions.filter(
                            (option: HTMLOptionElement) => option.value === value
                        )[0];

                        /**
                         * Let's iterate over original <option> data- attribute to reassign them to the <option>
                         * which choicejs generates
                         */
                        for (const [dataProperty, dataValue] of Object.entries(originalOption.dataset)) {
                            opt.dataset[dataProperty] = typeof dataValue === 'string' ? dataValue : undefined;
                        }

                        return opt;
                    }
                }
            }
        } as any);

cedricdo avatar Feb 28 '22 15:02 cedricdo

How can I re-write this in JS, not Typescript? Thank you

DuyTr avatar Aug 08 '22 20:08 DuyTr

I've tried this workaround on version 10.2.0 but I wasn't able to make it work

~It looks like that the _presetOptions do not keep the original data attributes (anymore?), and I can't find a way to access them once choices.js is initialized~ it is working 🤷🏻‍♂️

How can I re-write this in JS, not Typescript? Thank you

  // Needed because by default Choices does not transfer data attributes
  // to the javascript elements Choices-js/Choices#738
  callbackOnCreateTemplates: function () {
    return {
      option: ({ label, value, customProperties, active, disabled }) => {
        const opt = Choices.defaults.templates.option.call(this, { label, value, customProperties, active, disabled })

        const originalOption = this._presetOptions.filter((option) => option.value === value)[0]

        if (originalOption) {
          const dataset = originalOption.dataset || {}

          for (const [dataProperty, dataValue] of Object.entries(dataset)) {
            opt.dataset[dataProperty] = typeof dataValue === 'string' ? dataValue : undefined
          }
        }

        return opt
      }
    }

tagliala avatar Dec 15 '22 12:12 tagliala