diff --git a/api/js/etemplate/Et2Select/Et2Select.ts b/api/js/etemplate/Et2Select/Et2Select.ts
index e387ef45ae..87ab3e2069 100644
--- a/api/js/etemplate/Et2Select/Et2Select.ts
+++ b/api/js/etemplate/Et2Select/Et2Select.ts
@@ -580,7 +580,9 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
return html`
+ class="${option.class}" .option=${option}
+ ?disabled=${option.disabled}
+ >
${this._iconTemplate(option)}
${this.noLang ? option.label : this.egw().lang(option.label)}
`;
@@ -623,7 +625,7 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
{
tag.size = this.size;
}
- if(this.readonly)
+ if(this.readonly || item.option && typeof (item.option.disabled) != "undefined" && item.option.disabled)
{
tag.removable = false;
tag.readonly = true;
diff --git a/api/js/etemplate/Et2Select/FindSelectOptions.ts b/api/js/etemplate/Et2Select/FindSelectOptions.ts
index c4998ddcc3..50e22e3598 100644
--- a/api/js/etemplate/Et2Select/FindSelectOptions.ts
+++ b/api/js/etemplate/Et2Select/FindSelectOptions.ts
@@ -8,6 +8,9 @@ export interface SelectOption
icon? : string;
// Class applied to node
class? : string;
+ // Show the option, but it is not selectable.
+ // If multiple=true and the option is in the value, it is not removable.
+ disabled? : boolean;
}
/**
diff --git a/api/js/etemplate/Et2Select/SearchMixin.ts b/api/js/etemplate/Et2Select/SearchMixin.ts
index 622df63377..9fba2ee50e 100644
--- a/api/js/etemplate/Et2Select/SearchMixin.ts
+++ b/api/js/etemplate/Et2Select/SearchMixin.ts
@@ -1080,7 +1080,7 @@ export const Et2WithSearchMixin = >(superclass
// Reset remaining options. It might be faster to re-create instead.
this._menuItems.forEach((item) =>
{
- item.disabled = false;
+ item.disabled = item.option?.disabled || false;
item.classList.remove("match");
item.classList.remove("no-match");
});