forked from extern/egroupware
Work on LinkEntry
- fix missing app select - add clear button - use request() instead of json() to query server - add optional class property to SelectOption - move cleaning select options to its own function so we can use it anywhere - Use separate render to keep local / remote options separate. Local options stay in select_options.
This commit is contained in:
parent
cbe097b2e3
commit
2b68b6cbbe
@ -69,7 +69,10 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
||||
app: () =>
|
||||
{
|
||||
const app = <Et2LinkAppSelect>document.createElement("et2-link-apps")
|
||||
if(this.__only_app)
|
||||
{
|
||||
app.only_app = this.__only_app;
|
||||
}
|
||||
return app;
|
||||
},
|
||||
select: () =>
|
||||
@ -105,6 +108,7 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
||||
|
||||
protected __only_app : string;
|
||||
protected __app : string;
|
||||
protected __value : LinkEntry | string | number;
|
||||
|
||||
set only_app(app)
|
||||
{
|
||||
@ -121,8 +125,14 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
||||
set app(app)
|
||||
{
|
||||
this.__app = app;
|
||||
if (this._appNode) this._appNode.value = app;
|
||||
if (this._searchNode) this._searchNode.app = app;
|
||||
if(this._appNode)
|
||||
{
|
||||
this._appNode.value = app;
|
||||
}
|
||||
if(this._searchNode)
|
||||
{
|
||||
this._searchNode.app = app;
|
||||
}
|
||||
}
|
||||
|
||||
get app()
|
||||
@ -156,8 +166,6 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
||||
this._searchNode.app = this._appNode.value;
|
||||
}
|
||||
|
||||
protected __value : LinkEntry|string|number;
|
||||
|
||||
get value() : LinkEntry|string|number
|
||||
{
|
||||
if (this.only_app)
|
||||
@ -203,7 +211,6 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
||||
* @return {TemplateResult}
|
||||
* @protected
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
_inputGroupInputTemplate()
|
||||
{
|
||||
return html`
|
||||
|
@ -44,6 +44,7 @@ export class Et2LinkSearch extends Et2Select
|
||||
super();
|
||||
this.search = true;
|
||||
this.searchUrl = "EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_search";
|
||||
this.clearable = true;
|
||||
}
|
||||
|
||||
get _appNode() : Et2LinkAppSelect
|
||||
@ -53,7 +54,7 @@ export class Et2LinkSearch extends Et2Select
|
||||
|
||||
protected remoteQuery(search : string, options : object)
|
||||
{
|
||||
let request = this.egw().json(this.searchUrl, [this._appNode.value, '', search, options]);
|
||||
let request = this.egw().request(this.searchUrl, [this._appNode.value, '', search, options]);
|
||||
if(this.query && typeof this.query == "function")
|
||||
{
|
||||
if(!this.query(request, this))
|
||||
@ -61,16 +62,9 @@ export class Et2LinkSearch extends Et2Select
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ToDo use egw.request(), not old egw.json()
|
||||
request.sendRequest().then((result) =>
|
||||
request.then((result) =>
|
||||
{
|
||||
result.response.forEach((response) =>
|
||||
{
|
||||
if (typeof response.data !== 'undefined')
|
||||
{
|
||||
this.processRemoteResults(response.data);
|
||||
}
|
||||
});
|
||||
this.processRemoteResults(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ export class Et2Select extends Et2WithSearchMixin(Et2InvokerMixin(Et2WidgetWithS
|
||||
<et2-image slot="prefix" src="${option.icon}"></et2-image>` : "";
|
||||
|
||||
return html`
|
||||
<sl-menu-item value="${option.value}" title="${option.title}">
|
||||
<sl-menu-item value="${option.value}" title="${option.title}" class="${option.class}">
|
||||
${icon}
|
||||
${option.label}
|
||||
</sl-menu-item>`;
|
||||
|
@ -11,7 +11,7 @@ import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||
import {StaticOptions} from "./StaticOptions";
|
||||
import {dedupeMixin, html, PropertyValues, render, repeat, TemplateResult} from "@lion/core";
|
||||
import {et2_readAttrWithDefault} from "../et2_core_xml";
|
||||
import {find_select_options, SelectOption} from "./FindSelectOptions";
|
||||
import {cleanSelectOptions, find_select_options, SelectOption} from "./FindSelectOptions";
|
||||
|
||||
/**
|
||||
* Base class for things that do selectbox type behaviour, to avoid putting too much or copying into read-only
|
||||
@ -147,25 +147,9 @@ export const Et2widgetWithSelectMixin = dedupeMixin((superclass) =>
|
||||
set select_options(new_options : SelectOption[])
|
||||
{
|
||||
const old_options = this.__select_options;
|
||||
if(!Array.isArray(new_options))
|
||||
{
|
||||
let fixed_options = [];
|
||||
for(let key in <any>new_options)
|
||||
{
|
||||
let option : any = new_options[key];
|
||||
if (typeof option === 'string')
|
||||
{
|
||||
option = { label: option };
|
||||
}
|
||||
option.value = key.trim(); // link_search prefixes keys with one space
|
||||
fixed_options.push(option);
|
||||
}
|
||||
this.__select_options = fixed_options;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.__select_options = new_options;
|
||||
}
|
||||
|
||||
this.__select_options = cleanSelectOptions(new_options);
|
||||
|
||||
this.requestUpdate("select_options", old_options);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ export interface SelectOption
|
||||
title? : string;
|
||||
// Related image or icon
|
||||
icon? : string;
|
||||
// Class applied to node
|
||||
class? : string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,3 +212,36 @@ export function find_select_options(widget, attr_options?, options : SelectOptio
|
||||
}
|
||||
return content_options;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean up things that might be select options and get them to what we need to make
|
||||
* them consistent for widget use.
|
||||
*
|
||||
* Options might be just a list of labels, or an object of value => label pairs, etc.
|
||||
*
|
||||
* @param {SelectOption[] | string[] | object} options
|
||||
*/
|
||||
export function cleanSelectOptions(options : SelectOption[] | string[] | object) : SelectOption[]
|
||||
{
|
||||
let fixed_options = [];
|
||||
if(!Array.isArray(options))
|
||||
{
|
||||
for(let key in <any>options)
|
||||
{
|
||||
let option : any = options[key];
|
||||
if(typeof option === 'string')
|
||||
{
|
||||
option = {label: option};
|
||||
}
|
||||
option.value = key.trim(); // link_search prefixes keys with one space
|
||||
fixed_options.push(option);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_options = options;
|
||||
}
|
||||
|
||||
return fixed_options;
|
||||
}
|
@ -8,7 +8,8 @@
|
||||
*/
|
||||
|
||||
|
||||
import {css, dedupeMixin, html, LitElement, render, SlotMixin} from "@lion/core";
|
||||
import {css, dedupeMixin, html, LitElement, render, repeat, SlotMixin} from "@lion/core";
|
||||
import {cleanSelectOptions, SelectOption} from "./FindSelectOptions";
|
||||
|
||||
|
||||
// Export the Interface for TypeScript
|
||||
@ -295,7 +296,7 @@ export const Et2WithSearchMixin = dedupeMixin((superclass) =>
|
||||
if(this.getItems().length === 1)
|
||||
{
|
||||
this.getItems()[0].click();
|
||||
// not jQuery this.hide();
|
||||
this.dropdown.hide();
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
@ -392,7 +393,18 @@ export const Et2WithSearchMixin = dedupeMixin((superclass) =>
|
||||
*/
|
||||
protected processRemoteResults(results)
|
||||
{
|
||||
this.select_options = results;
|
||||
let entries = cleanSelectOptions(results);
|
||||
|
||||
// Add a "remote" class so we can tell these apart from any local results
|
||||
entries.forEach((entry) => entry.class = entry.class += "remote");
|
||||
|
||||
let target = this._optionTargetNode || this;
|
||||
if(target)
|
||||
{
|
||||
render(html`${repeat(<SelectOption[]>entries, (option : SelectOption) => option.value, this._optionTemplate.bind(this))}`,
|
||||
target
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user