}
export class UiItemListLineBreakSeparatedText {
+ protected addButton?: HTMLAnchorElement = undefined;
protected clearButton?: HTMLAnchorElement = undefined;
protected itemInput?: HTMLInputElement = undefined;
protected readonly itemList: HTMLUListElement;
protected readonly items = new Set<string>();
+ protected readonly mutationObserver: MutationObserver;
protected readonly options: LineBreakSeparatedTextOptions;
protected readonly submitField?: HTMLInputElement = undefined;
+ protected uiDisabled = false;
constructor(itemList: HTMLUListElement, options: LineBreakSeparatedTextOptions = {}) {
this.itemList = itemList;
this.itemList.closest("form")!.addEventListener("submit", () => this.submit());
+ // The UI can be used for user group option types which can be enabled/disabled by changing the
+ // `readonly` attribute, which has to be observed to enable/disable the UI.
+ this.mutationObserver = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ if (mutation.attributeName === "readonly") {
+ const input = mutation.target as HTMLInputElement;
+
+ if (input.readOnly) {
+ this.disableUi();
+ } else {
+ this.enableUi();
+ }
+ }
+ });
+ });
+
this.initValues();
this.buildUi();
}
protected addItem(event: Event): void {
event.preventDefault();
+ if (this.uiDisabled) {
+ return;
+ }
+
const itemInput = this.itemInput!;
const item = itemInput.value.trim();
this.itemInput.addEventListener("keydown", (ev) => this.keydown(ev));
this.itemInput.addEventListener("paste", (ev) => this.paste(ev));
inputAddon.appendChild(this.itemInput);
+ this.mutationObserver.observe(this.itemInput, {
+ attributes: true,
+ });
- const addButton = document.createElement("a");
- addButton.href = "#";
- addButton.classList.add("button", "inputSuffix", "jsTooltip");
- addButton.title = Language.get("wcf.global.button.add");
- addButton.innerHTML = '<span class="icon icon16 fa-plus"></span>';
- addButton.addEventListener("click", (ev) => this.addItem(ev));
- inputAddon.appendChild(addButton);
+ this.addButton = document.createElement("a");
+ this.addButton.href = "#";
+ this.addButton.classList.add("button", "inputSuffix", "jsTooltip");
+ this.addButton.title = Language.get("wcf.global.button.add");
+ this.addButton.innerHTML = '<span class="icon icon16 fa-plus"></span>';
+ this.addButton.addEventListener("click", (ev) => this.addItem(ev));
+ inputAddon.appendChild(this.addButton);
this.clearButton = document.createElement("a");
this.clearButton.href = "#";
/**
* Clears the item list after clicking on the clear button.
*/
- protected clearList(ev: Event): void {
- ev.preventDefault();
+ protected clearList(event: Event): void {
+ event.preventDefault();
+
+ if (this.uiDisabled) {
+ return;
+ }
UiConfirmation.show({
confirm: () => {
* Deletes an item from the list after clicking on its delete icon.
*/
protected deleteItem(event: Event): void {
+ if (this.uiDisabled) {
+ return;
+ }
+
const button = event.currentTarget as HTMLElement;
const item = button.closest("li")!.dataset.value!;
});
}
+ /**
+ * Disables the user interface after the input field has been set readonly.
+ */
+ protected disableUi(): void {
+ this.addButton!.classList.add("disabled");
+ this.clearButton!.classList.add("disabled");
+
+ this.itemList.querySelectorAll(".jsDeleteItem").forEach((button) => button.classList.add("disabled"));
+
+ this.uiDisabled = true;
+ }
+
+ /**
+ * Enables the user interface after the input field is no longer readonly.
+ */
+ protected enableUi(): void {
+ this.addButton!.classList.remove("disabled");
+ this.clearButton!.classList.remove("disabled");
+
+ this.itemList.querySelectorAll(".jsDeleteItem").forEach((button) => button.classList.remove("disabled"));
+
+ this.uiDisabled = false;
+ }
+
/**
* Hides the item list and clear button.
*/
* field.
*/
protected paste(event: ClipboardEvent): void {
+ if (this.uiDisabled) {
+ return;
+ }
+
const items = event.clipboardData!.getData("text/plain").split("\n");
if (items.length > 1) {
event.preventDefault();
Util_1 = tslib_1.__importDefault(Util_1);
class UiItemListLineBreakSeparatedText {
constructor(itemList, options = {}) {
+ this.addButton = undefined;
this.clearButton = undefined;
this.itemInput = undefined;
this.items = new Set();
this.submitField = undefined;
+ this.uiDisabled = false;
this.itemList = itemList;
this.options = options;
if (!this.options.submitFieldName) {
}
}
this.itemList.closest("form").addEventListener("submit", () => this.submit());
+ // The UI can be used for user group option types which can be enabled/disabled by changing the
+ // `readonly` attribute, which has to be observed to enable/disable the UI.
+ this.mutationObserver = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ if (mutation.attributeName === "readonly") {
+ const input = mutation.target;
+ if (input.readOnly) {
+ this.disableUi();
+ }
+ else {
+ this.enableUi();
+ }
+ }
+ });
+ });
this.initValues();
this.buildUi();
}
*/
addItem(event) {
event.preventDefault();
+ if (this.uiDisabled) {
+ return;
+ }
const itemInput = this.itemInput;
const item = itemInput.value.trim();
if (item === "") {
this.itemInput.addEventListener("keydown", (ev) => this.keydown(ev));
this.itemInput.addEventListener("paste", (ev) => this.paste(ev));
inputAddon.appendChild(this.itemInput);
- const addButton = document.createElement("a");
- addButton.href = "#";
- addButton.classList.add("button", "inputSuffix", "jsTooltip");
- addButton.title = Language.get("wcf.global.button.add");
- addButton.innerHTML = '<span class="icon icon16 fa-plus"></span>';
- addButton.addEventListener("click", (ev) => this.addItem(ev));
- inputAddon.appendChild(addButton);
+ this.mutationObserver.observe(this.itemInput, {
+ attributes: true,
+ });
+ this.addButton = document.createElement("a");
+ this.addButton.href = "#";
+ this.addButton.classList.add("button", "inputSuffix", "jsTooltip");
+ this.addButton.title = Language.get("wcf.global.button.add");
+ this.addButton.innerHTML = '<span class="icon icon16 fa-plus"></span>';
+ this.addButton.addEventListener("click", (ev) => this.addItem(ev));
+ inputAddon.appendChild(this.addButton);
this.clearButton = document.createElement("a");
this.clearButton.href = "#";
this.clearButton.classList.add("button", "inputSuffix", "jsTooltip");
/**
* Clears the item list after clicking on the clear button.
*/
- clearList(ev) {
- ev.preventDefault();
+ clearList(event) {
+ event.preventDefault();
+ if (this.uiDisabled) {
+ return;
+ }
UiConfirmation.show({
confirm: () => {
this.itemList.innerHTML = "";
* Deletes an item from the list after clicking on its delete icon.
*/
deleteItem(event) {
+ if (this.uiDisabled) {
+ return;
+ }
const button = event.currentTarget;
const item = button.closest("li").dataset.value;
UiConfirmation.show({
messageIsHtml: true,
});
}
+ /**
+ * Disables the user interface after the input field has been set readonly.
+ */
+ disableUi() {
+ this.addButton.classList.add("disabled");
+ this.clearButton.classList.add("disabled");
+ this.itemList.querySelectorAll(".jsDeleteItem").forEach((button) => button.classList.add("disabled"));
+ this.uiDisabled = true;
+ }
+ /**
+ * Enables the user interface after the input field is no longer readonly.
+ */
+ enableUi() {
+ this.addButton.classList.remove("disabled");
+ this.clearButton.classList.remove("disabled");
+ this.itemList.querySelectorAll(".jsDeleteItem").forEach((button) => button.classList.remove("disabled"));
+ this.uiDisabled = false;
+ }
/**
* Hides the item list and clear button.
*/
* field.
*/
paste(event) {
+ if (this.uiDisabled) {
+ return;
+ }
const items = event.clipboardData.getData("text/plain").split("\n");
if (items.length > 1) {
event.preventDefault();