110 lines
3.4 KiB
JavaScript
110 lines
3.4 KiB
JavaScript
import { L5r5eHtmlMultiSelectElement } from "../misc/l5r5e-multiselect.js";
|
|
|
|
/**
|
|
* A Foundry `SetField` that renders as an {@link L5r5eHtmlMultiSelectElement} chip-input.
|
|
*
|
|
* Use this in a DataModel schema whenever a field stores an unordered collection of
|
|
* string values drawn from a fixed option list. On form submission the element returns a
|
|
* comma-separated string; `clean()` splits it back into an Array before Foundry processes
|
|
* it, and `initialize()` wraps the result in a `Set` for use in the model.
|
|
*
|
|
* @example
|
|
* // In a DataModel schema:
|
|
* skills: new L5r5eSetField({
|
|
* options: [
|
|
* { value: "athletics", label: "Athletics" },
|
|
* { value: "meditation", label: "Meditation", disabled: true, tooltip: "Requires rank 3" },
|
|
* ]
|
|
* })
|
|
*
|
|
* // Renders automatically via {{formGroup}} in a Handlebars template:
|
|
* // {{formGroup fields.skills name="skills" value=data.skills localize=true}}
|
|
*
|
|
* @param {object} options
|
|
* @param {{ value: string, label: string, disabled?: boolean, tooltip?: string }[]} options.options
|
|
* Flat list of selectable items. Passed directly to {@link L5r5eHtmlMultiSelectElement.create}.
|
|
* @param {object[]} [options.groups]
|
|
* Optional optgroup definitions, forwarded to the element factory unchanged.
|
|
* @param {boolean} [options.hideDisabledOptions=false]
|
|
* When true, disabled options are hidden from the dropdown instead of greyed out.
|
|
*/
|
|
export class L5r5eSetField extends foundry.data.fields.SetField {
|
|
/**
|
|
* Saved constructor options, used to reconstruct the multiselect input on form render.
|
|
* @type {object}
|
|
*/
|
|
#savedOptions;
|
|
|
|
/**
|
|
* @param {object} options
|
|
* @param {object} context
|
|
*/
|
|
constructor(options = {}, context = {}) {
|
|
super(
|
|
new foundry.data.fields.StringField({
|
|
choices: options.options?.map((option) => option.value) ?? [],
|
|
}),
|
|
options,
|
|
context
|
|
);
|
|
|
|
this.#savedOptions = options;
|
|
}
|
|
|
|
/**
|
|
* @param {*} value
|
|
* @param {object} model
|
|
* @param {object} options
|
|
* @return {Set}
|
|
* @override
|
|
*/
|
|
initialize(value, model, options = {}) {
|
|
if (!value || (Array.isArray(value) && value.length === 0)) {
|
|
return new Set();
|
|
}
|
|
|
|
return new Set(super.initialize(value, model, options).filter(Boolean));
|
|
}
|
|
|
|
/**
|
|
* @param {Set} value
|
|
* @return {*[]|*}
|
|
* @override
|
|
*/
|
|
toObject(value) {
|
|
if (!value) {
|
|
return value;
|
|
}
|
|
return Array.from(value).map((v) => this.element.toObject(v));
|
|
}
|
|
|
|
/**
|
|
* @param {string|Array} value
|
|
* @param {object} options
|
|
* @return {Array}
|
|
* @override
|
|
*/
|
|
clean(value, options) {
|
|
// Settings forms submit comma-separated strings; split before normal cleaning.
|
|
if (typeof value === "string") {
|
|
value = value.length ? value.split(",").filter(Boolean) : [];
|
|
}
|
|
return super.clean(value, options);
|
|
}
|
|
|
|
/**
|
|
* @param {object} config
|
|
* @return {L5r5eHtmlMultiSelectElement}
|
|
* @override
|
|
*/
|
|
_toInput(config) {
|
|
return L5r5eHtmlMultiSelectElement.create({
|
|
name: config.name,
|
|
options: this.#savedOptions.options,
|
|
groups: this.#savedOptions.groups,
|
|
value: config.value,
|
|
localize: config.localize,
|
|
hideDisabledOptions: this.#savedOptions.hideDisabledOptions,
|
|
});
|
|
}
|
|
} |