2020-06-29 03:12:44 +02:00
|
|
|
import {UIElement} from "../UIElement";
|
2020-07-20 21:39:07 +02:00
|
|
|
import {InputElement} from "./InputElement";
|
2020-07-21 00:38:03 +02:00
|
|
|
import Translations from "../i18n/Translations";
|
2020-08-17 17:23:15 +02:00
|
|
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
2020-06-28 00:06:23 +02:00
|
|
|
|
2020-07-20 21:39:07 +02:00
|
|
|
export class DropDown<T> extends InputElement<T> {
|
2020-06-28 00:06:23 +02:00
|
|
|
|
2020-07-21 00:38:03 +02:00
|
|
|
private readonly _label: UIElement;
|
2020-07-20 21:39:07 +02:00
|
|
|
private readonly _values: { value: T; shown: UIElement }[];
|
2020-06-28 00:06:23 +02:00
|
|
|
|
2020-08-31 02:59:47 +02:00
|
|
|
private readonly _value: UIEventSource<T>;
|
|
|
|
|
|
|
|
public IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
2020-07-20 21:39:07 +02:00
|
|
|
|
2020-07-21 00:38:03 +02:00
|
|
|
constructor(label: string | UIElement,
|
2020-07-20 21:39:07 +02:00
|
|
|
values: { value: T, shown: string | UIElement }[],
|
|
|
|
value: UIEventSource<T> = undefined) {
|
2020-06-28 00:06:23 +02:00
|
|
|
super(undefined);
|
2020-07-20 21:39:07 +02:00
|
|
|
this._value = value ?? new UIEventSource<T>(undefined);
|
2020-07-21 00:38:03 +02:00
|
|
|
this._label = Translations.W(label);
|
2020-07-20 21:39:07 +02:00
|
|
|
this._values = values.map(v => {
|
2020-08-31 02:59:47 +02:00
|
|
|
return {
|
|
|
|
value: v.value,
|
2020-07-21 00:38:03 +02:00
|
|
|
shown: Translations.W(v.shown)
|
2020-07-20 21:39:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2020-07-21 00:38:03 +02:00
|
|
|
for (const v of this._values) {
|
|
|
|
this.ListenTo(v.shown._source);
|
|
|
|
}
|
2020-07-22 16:44:07 +02:00
|
|
|
this.ListenTo(this._value);
|
|
|
|
|
|
|
|
this.onClick(() => {}) // by registering a click, the click event is consumed and doesn't bubble furter to other elements, e.g. checkboxes
|
|
|
|
|
2020-07-20 21:39:07 +02:00
|
|
|
|
2020-06-28 00:06:23 +02:00
|
|
|
}
|
|
|
|
|
2020-07-20 21:39:07 +02:00
|
|
|
GetValue(): UIEventSource<T> {
|
|
|
|
return this._value;
|
|
|
|
}
|
|
|
|
IsValid(t: T): boolean {
|
2020-06-28 00:06:23 +02:00
|
|
|
for (const value of this._values) {
|
2020-07-20 21:39:07 +02:00
|
|
|
if (value.value === t) {
|
|
|
|
return true;
|
|
|
|
}
|
2020-06-28 00:06:23 +02:00
|
|
|
}
|
2020-07-20 21:39:07 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
InnerRender(): string {
|
2020-07-21 00:07:04 +02:00
|
|
|
if(this._values.length <=1){
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2020-07-20 21:39:07 +02:00
|
|
|
let options = "";
|
|
|
|
for (let i = 0; i < this._values.length; i++) {
|
|
|
|
options += "<option value='" + i + "'>" + this._values[i].shown.InnerRender() + "</option>"
|
|
|
|
}
|
2020-07-23 16:00:49 +02:00
|
|
|
|
2020-06-28 00:06:23 +02:00
|
|
|
return "<form>" +
|
2020-07-25 18:00:08 +02:00
|
|
|
"<label for='dropdown-" + this.id + "'>" + this._label.Render() + " </label>" +
|
2020-06-28 00:06:23 +02:00
|
|
|
"<select name='dropdown-" + this.id + "' id='dropdown-" + this.id + "'>" +
|
|
|
|
options +
|
|
|
|
"</select>" +
|
|
|
|
"</form>";
|
|
|
|
}
|
|
|
|
|
2020-07-20 21:39:07 +02:00
|
|
|
protected InnerUpdate(element) {
|
|
|
|
var e = document.getElementById("dropdown-" + this.id);
|
2020-07-21 00:07:04 +02:00
|
|
|
if(e === null){
|
|
|
|
return;
|
|
|
|
}
|
2020-06-28 00:06:23 +02:00
|
|
|
const self = this;
|
2020-07-20 21:39:07 +02:00
|
|
|
e.onchange = (() => {
|
2020-07-01 17:38:48 +02:00
|
|
|
// @ts-ignore
|
2020-07-20 21:39:07 +02:00
|
|
|
var index = parseInt(e.selectedIndex);
|
|
|
|
self._value.setData(self._values[index].value);
|
|
|
|
});
|
|
|
|
|
|
|
|
var t = this._value.data;
|
|
|
|
for (let i = 0; i < this._values.length ; i++) {
|
2020-07-24 14:46:25 +02:00
|
|
|
const value = this._values[i].value;
|
|
|
|
if (value === t) {
|
2020-07-20 21:39:07 +02:00
|
|
|
// @ts-ignore
|
|
|
|
e.selectedIndex = i;
|
|
|
|
}
|
2020-06-28 00:06:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|