diff --git a/api/js/etemplate/Et2Select/Et2Select.ts b/api/js/etemplate/Et2Select/Et2Select.ts
index d768417fb3..73de819c2a 100644
--- a/api/js/etemplate/Et2Select/Et2Select.ts
+++ b/api/js/etemplate/Et2Select/Et2Select.ts
@@ -505,65 +505,6 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
}
}
- /**
- * Override this method from SlSelect to stick our own tags in there
- *
- syncItemsFromValue()
- {
- if(typeof super.syncItemsFromValue === "function")
- {
- super.syncItemsFromValue();
- }
-
- // Only applies to multiple
- if(typeof this.displayTags !== "object" || !this.multiple)
- {
- return;
- }
-
- let overflow = null;
- if(this.maxOptionsVisible > 0 && this.displayTags.length > this.maxOptionsVisible)
- {
- overflow = this.displayTags.pop();
- }
-
- const checkedItems = Object.values(this._menuItems).filter(item => this.value.includes(item.value));
- this.displayTags = checkedItems.map(item => this._createTagNode(item));
-
- if(checkedItems.length !== this.value.length && this.multiple)
- {
- // There's a value that does not have a menu item, probably invalid.
- // Add it as a marked tag so it can be corrected or removed.
- const filteredValues = this.value.filter(str => !checkedItems.some(obj => obj.value === str));
- for(let i = 0; i < filteredValues.length; i++)
- {
- const badTag = this._createTagNode({
- value: filteredValues[i],
- getTextLabel: () => filteredValues[i],
- classList: {value: ""}
- });
- badTag.variant = "danger";
- badTag.contactPlus = false;
- // Put it in front so it shows
- this.displayTags.unshift(badTag);
- }
- }
-
- // Re-slice & add overflow tag
- if(overflow)
- {
- this.displayTags = this.displayTags.slice(0, this.maxOptionsVisible);
- this.displayTags.push(overflow);
- }
- else if(this.multiple && this.rows == 1 && this.readonly && this.value.length > 1)
- {
- // Maybe more tags than we can show, show the count
- this.displayTags.push(html`
- ${this.value.length} `);
- }
- }
- */
-
/**
* Tag used for rendering tags when multiple=true
* Used for creating, finding & filtering options.
@@ -616,6 +557,12 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
{
super.handleOptionClick(event);
+ // Only interested in option clicks, but handler is bound higher
+ if(event.target.tagName !== "SL-OPTION")
+ {
+ return;
+ }
+
if(this._close_on_select)
{
this.hide();
@@ -878,6 +825,7 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
.maxOptionsVisible=${0}
.value=${value}
@sl-change=${this.handleValueChange}
+ @mouseup=${this.handleOptionClick}
>
${icon}
${this._emptyLabelTemplate()}
diff --git a/api/js/etemplate/Et2Select/SearchMixin.ts b/api/js/etemplate/Et2Select/SearchMixin.ts
index a444d854b7..798e46646a 100644
--- a/api/js/etemplate/Et2Select/SearchMixin.ts
+++ b/api/js/etemplate/Et2Select/SearchMixin.ts
@@ -789,6 +789,24 @@ export const Et2WithSearchMixin = dedupeMixin(
event.preventDefault();
return false;
}
+
+ // Find and keep any selected remote entries
+ // Doing it here catches keypress changes too
+ this.select.querySelectorAll("[aria-selected=true].remote").forEach((node) =>
+ {
+ const value = node.value.replaceAll("___", " ");
+ if(!node.selected || this._selected_remote.some(o => o.value == value))
+ {
+ return;
+ }
+ const remote_option_index = this._remote_options.findIndex(o => o.value == value);
+ if(remote_option_index >= 0)
+ {
+ console.log("Keeping " + value, this._remote_options[remote_option_index]);
+ this._selected_remote.push(node.option);
+ this._remote_options.splice(remote_option_index, 1);
+ }
+ });
return true;
}
@@ -827,11 +845,13 @@ export const Et2WithSearchMixin = dedupeMixin(
*/
handleOptionClick(event)
{
- // Need to keep the remote option - only if selected
- if(event.target.classList.contains("remote") && !this.select_options.find(o => o.value == event.target.value))
+ // Only interested in option clicks, but handler is bound higher
+ if(event.target.tagName !== "SL-OPTION")
{
- this._selected_remote.push({...event.target.option});
+ return;
}
+
+ if(typeof super.handleOptionClick == "function")
super.handleOptionClick(event);
this.updateComplete.then(() =>
@@ -841,25 +861,6 @@ export const Et2WithSearchMixin = dedupeMixin(
{
this._searchInputNode.focus();
this._searchInputNode.select();
-
- // If we were overlapping, reset
- if(this._activeControls.classList.contains("novalue"))
- {
- this._handleMenuShow();
- this._handleAfterShow();
- }
-
- // Scroll the new tag into view
- if(event.detail)
- {
- // Causes sidemenu (calendar) to scroll to top & get stuck
- /*
- this.updateComplete.then(() =>
- {
- this.shadowRoot.querySelector("et2-tag[value='" + event.detail.item.value.replace(/'/g, "\\\'") + "']")?.scrollIntoView({block: "nearest"});
- });
- */
- }
}
else if(!this.multiple && this.searchEnabled)
{
@@ -1086,13 +1087,10 @@ export const Et2WithSearchMixin = dedupeMixin(
// Remove any previously selected remote options that aren't used anymore
this._selected_remote = this._selected_remote.filter((option) =>
{
- return this.multiple ? this.value.indexOf(option.value) != -1 : this.value == option.value;
+ return this.multiple ? this.value.indexOf(option.value) != -1 : this.value == option.value;
});
- // Remove remote options that aren't used
- let keepers = this._selected_remote.reduce((prev, current) =>
- {
- return prev + ":not([value='" + ('' + current.value).replace(/'/g, "\\\'") + "'])";
- }, "");
+
+ this._remote_options = [];
// Not searching anymore, clear flag
this.select_options.map((o) => o.isMatch = null);
@@ -1234,24 +1232,19 @@ export const Et2WithSearchMixin = dedupeMixin(
return Promise.resolve();
}
// Add a "remote" class so we can tell these apart from any local results
- entries.forEach((entry) =>
+ for(let i = entries.length - 1; i >= 0; i--)
{
+ const entry = entries[i];
entry.class = (entry.class || "") + " remote";
// Server says it's a match
entry.isMatch = true;
- });
-
- // Add in remote options, avoiding duplicates
- this.select_options.filter(function(item)
- {
- let i = entries.findIndex(x => (x.value == item.value));
- if(i <= -1)
+ // Avoid duplicates with existing options
+ if(this.select_options.some(o => o.value == entry.value))
{
- entries.push(item);
+ entries.splice(i, 1);
}
- return null;
- });
+ }
this._remote_options = entries;
this.requestUpdate("select_options");