Skip to content

Instantly share code, notes, and snippets.

@vladdancer
Created February 8, 2025 15:46
Show Gist options
  • Save vladdancer/7f8283afac83f09984cd22e7ec9a6ff2 to your computer and use it in GitHub Desktop.
Save vladdancer/7f8283afac83f09984cd22e7ec9a6ff2 to your computer and use it in GitHub Desktop.
Simple registry for Choices widgets #choices.js
import Choices from "choices.js";
import set from 'lodash/set';
import get from 'lodash/get';
window.Choices = Choices;
/**
* @var {object}
*/
let widgetStorage = {};
/**
* Simple registry for Choices widgets.
*
* Based on Lodash .set/.get utility functions.
*
* Store instances references in a given storage.
* Register widget by random UUID and add widget id into HTML element.
*
* Usage:
* @code
* import ChoicesWidgetRegistry from './ChoicesWidgetRegistry.js'
* // if you need to expose it to other scripts:
* // window.ChoicesWidgetRegistry = ChoicesWidgetRegistry;
* // if you need to override default storage.
* // ChoicesWidgetRegistry.setWidgetStorage(myCustomObject);
* const widget = ChoiceWidgetRegistry.createWidget(element, {});
* // some in another place:
* // ChoiceWidgetRegistry.getWidget()
* const widget = ChoiceWidgetRegistry.getWidget(element);
* @endcode
*/
export default class ChoicesWidgetRegistry {
/**
* Create choices instance and register it in global registry.
*
* @param element
* @param config
* @returns {Choices}
*/
static createWidget(element, config) {
const widget = new Choices(element, config);
const widgetId = crypto.randomUUID();
element.setAttribute('data-widget-id', widgetId);
set(widgetStorage, `choices.widgets.${widgetId}`, widget);
return widget;
}
/**
* Override registry storage, otherwise use default global object.
*
* @param storage
*/
static setWidgetStorage(storage) {
widgetStorage = storage;
}
/**
* Find choices instance by data-widget-id attribute.
*
* @param {HTMLElement} element
* @param {object} config
* Choices config.
* @returns {Choices|undefined} Choices instance.
*/
static getOrCreateWidget(element, config) {
let instance = this.getWidget(element);
return typeof instance !== 'undefined'
? instance
: this.createWidget(element, typeof config === 'object' ? config : null);
}
/**
* Lookup choices instance by getting widget id from given HTML element.
*
* @param {HTMLElement} element
* @returns {Choices|undefined} Choices instance.
*/
static getWidget(element) {
let widget = null;
const widgetId = element.getAttribute('data-widget-id');
if (widgetId) {
widget = get(widgetStorage, `choices.widgets.${widgetId}`);
}
return widget;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment