mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-24 06:48:40 +01:00
Select / Search bugs:
- search result would only be shown once even if next search included it - selected values disappear when starting a new search - loading spinner was not shown
This commit is contained in:
parent
6b950900ee
commit
851a054599
@ -351,9 +351,10 @@ export class Et2Select extends Et2WithSearchMixin(Et2InvokerMixin(Et2WidgetWithS
|
|||||||
<et2-image slot="prefix" part="icon" style="width: var(--icon-width)"
|
<et2-image slot="prefix" part="icon" style="width: var(--icon-width)"
|
||||||
src="${option.icon}"></et2-image>` : "";
|
src="${option.icon}"></et2-image>` : "";
|
||||||
|
|
||||||
// Tag used must match this.optionTag, but you can't use the variable directly
|
// Tag used must match this.optionTag, but you can't use the variable directly.
|
||||||
|
// Pass option along so SearchMixin can grab it if needed
|
||||||
return html`
|
return html`
|
||||||
<sl-menu-item value="${option.value}" title="${option.title}" class="${option.class}">
|
<sl-menu-item value="${option.value}" title="${option.title}" class="${option.class}" .option=${option}>
|
||||||
${icon}
|
${icon}
|
||||||
${option.label}
|
${option.label}
|
||||||
</sl-menu-item>`;
|
</sl-menu-item>`;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import {css, html, LitElement, render, repeat, SlotMixin} from "@lion/core";
|
import {css, html, LitElement, render, SlotMixin} from "@lion/core";
|
||||||
import {cleanSelectOptions, SelectOption} from "./FindSelectOptions";
|
import {cleanSelectOptions, SelectOption} from "./FindSelectOptions";
|
||||||
import {Validator} from "@lion/form-core";
|
import {Validator} from "@lion/form-core";
|
||||||
import {Et2Tag} from "./Tag/Et2Tag";
|
import {Et2Tag} from "./Tag/Et2Tag";
|
||||||
@ -117,10 +117,6 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
...(super.styles ? (Symbol.iterator in Object(super.styles) ? super.styles : [super.styles]) : []),
|
...(super.styles ? (Symbol.iterator in Object(super.styles) ? super.styles : [super.styles]) : []),
|
||||||
css`
|
css`
|
||||||
/* Show / hide SlSelect icons - dropdown arrow, etc */
|
|
||||||
::slotted([slot="suffix"]) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
:host([search]) ::slotted([slot="suffix"]) {
|
:host([search]) ::slotted([slot="suffix"]) {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
@ -139,7 +135,8 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
.select--standard.select--focused:not(.select--disabled) .select__control {
|
.select--standard.select--focused:not(.select--disabled) .select__control {
|
||||||
box-shadow: initial;
|
box-shadow: initial;
|
||||||
}
|
}
|
||||||
:host([allowFreeEntries]) ::slotted([slot="suffix"]) {
|
/* Show / hide SlSelect icons - dropdown arrow, etc but not loading spinner */
|
||||||
|
:host([allowFreeEntries]) ::slotted(sl-icon[slot="suffix"]) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
/* Make search textbox take full width */
|
/* Make search textbox take full width */
|
||||||
@ -206,6 +203,9 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
private _searchTimeout : number;
|
private _searchTimeout : number;
|
||||||
protected static SEARCH_TIMEOUT = 500;
|
protected static SEARCH_TIMEOUT = 500;
|
||||||
protected static MIN_CHARS = 2;
|
protected static MIN_CHARS = 2;
|
||||||
|
// Hold the original option data from earlier search results, since we discard on subsequent search
|
||||||
|
private _selected_remote = <SelectOption[]>[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These characters will end a free tag
|
* These characters will end a free tag
|
||||||
* @type {string[]}
|
* @type {string[]}
|
||||||
@ -367,12 +367,12 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
*
|
*
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
protected get localItems()
|
protected get localItems() : NodeList
|
||||||
{
|
{
|
||||||
return this.querySelectorAll(this.optionTag + ":not(.remote)");
|
return this.querySelectorAll(this.optionTag + ":not(.remote)");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected get remoteItems()
|
protected get remoteItems() : NodeList
|
||||||
{
|
{
|
||||||
return this.querySelectorAll(this.optionTag + ".remote");
|
return this.querySelectorAll(this.optionTag + ".remote");
|
||||||
}
|
}
|
||||||
@ -476,6 +476,12 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
*/
|
*/
|
||||||
_handleSelect(event)
|
_handleSelect(event)
|
||||||
{
|
{
|
||||||
|
// Need to keep the remote option - only if selected
|
||||||
|
if(event.detail.item.classList.contains("remote") && !this._selected_remote.find(o => o.value == event.detail.item.value))
|
||||||
|
{
|
||||||
|
this._selected_remote.push({...event.detail.item.option});
|
||||||
|
}
|
||||||
|
|
||||||
// If they just chose one from the list, re-focus the search
|
// If they just chose one from the list, re-focus the search
|
||||||
if(this.multiple && this.searchEnabled)
|
if(this.multiple && this.searchEnabled)
|
||||||
{
|
{
|
||||||
@ -497,6 +503,8 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
*/
|
*/
|
||||||
_handleClear()
|
_handleClear()
|
||||||
{
|
{
|
||||||
|
this._selected_remote = [];
|
||||||
|
|
||||||
if(!this.multiple && this.searchEnabled)
|
if(!this.multiple && this.searchEnabled)
|
||||||
{
|
{
|
||||||
// Restore label styling
|
// Restore label styling
|
||||||
@ -514,6 +522,7 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
*/
|
*/
|
||||||
protected _handleSearchKeyDown(event : KeyboardEvent)
|
protected _handleSearchKeyDown(event : KeyboardEvent)
|
||||||
{
|
{
|
||||||
|
clearTimeout(this._searchTimeout);
|
||||||
this._activeControls?.classList.add("active");
|
this._activeControls?.classList.add("active");
|
||||||
this.dropdown.show();
|
this.dropdown.show();
|
||||||
|
|
||||||
@ -533,20 +542,20 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
{
|
{
|
||||||
this.dropdown.hide();
|
this.dropdown.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(event.key == "Enter")
|
else if(event.key == "Enter")
|
||||||
{
|
{
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.startSearch();
|
this.startSearch();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if(event.key == "Escape")
|
else if(event.key == "Escape")
|
||||||
{
|
{
|
||||||
this._handleSearchAbort(event);
|
this._handleSearchAbort(event);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the search automatically if they have enough letters
|
// Start the search automatically if they have enough letters
|
||||||
clearTimeout(this._searchTimeout);
|
|
||||||
if(this._searchInputNode.value.length >= Et2WidgetWithSearch.MIN_CHARS)
|
if(this._searchInputNode.value.length >= Et2WidgetWithSearch.MIN_CHARS)
|
||||||
{
|
{
|
||||||
this._searchTimeout = window.setTimeout(() => {this.startSearch()}, Et2WidgetWithSearch.SEARCH_TIMEOUT);
|
this._searchTimeout = window.setTimeout(() => {this.startSearch()}, Et2WidgetWithSearch.SEARCH_TIMEOUT);
|
||||||
@ -577,6 +586,9 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
*/
|
*/
|
||||||
public startSearch()
|
public startSearch()
|
||||||
{
|
{
|
||||||
|
// Stop timeout timer
|
||||||
|
clearTimeout(this._searchTimeout);
|
||||||
|
|
||||||
// Show a spinner instead of search button
|
// Show a spinner instead of search button
|
||||||
this._searchButtonNode.style.display = "hidden";
|
this._searchButtonNode.style.display = "hidden";
|
||||||
let spinner = document.createElement("sl-spinner");
|
let spinner = document.createElement("sl-spinner");
|
||||||
@ -622,9 +634,6 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
*/
|
*/
|
||||||
protected remoteSearch(search : string, options : object)
|
protected remoteSearch(search : string, options : object)
|
||||||
{
|
{
|
||||||
// Remove existing remote items
|
|
||||||
this.remoteItems.forEach(i => i.remove());
|
|
||||||
|
|
||||||
if(!this.searchUrl)
|
if(!this.searchUrl)
|
||||||
{
|
{
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
@ -670,7 +679,8 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
if(target)
|
if(target)
|
||||||
{
|
{
|
||||||
// Keep local options first, add in remote options
|
// Keep local options first, add in remote options
|
||||||
this.select_options.filter(function(item)
|
// Include already selected remote entries, or they will be removed and we lose icon/class
|
||||||
|
this.select_options.concat(this._selected_remote).filter(function(item)
|
||||||
{
|
{
|
||||||
let i = entries.findIndex(x => (x.value == item.value));
|
let i = entries.findIndex(x => (x.value == item.value));
|
||||||
if(i <= -1)
|
if(i <= -1)
|
||||||
@ -680,7 +690,8 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
render(html`${repeat(<SelectOption[]>entries, (option : SelectOption) => option.value, this._optionTemplate.bind(this))}`,
|
//render(html`${repeat(<SelectOption[]>entries, (option : SelectOption) => option.value, this._optionTemplate.bind(this))}`,
|
||||||
|
render(entries.map((option) => this._optionTemplate(option)),
|
||||||
target
|
target
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user