| 
									
										
										
										
											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"; | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | import BaseUIElement from "../BaseUIElement"; | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |     private static _nextDropdownId = 0; | 
					
						
							|  |  |  |     public IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false); | 
					
						
							| 
									
										
										
										
											2020-06-28 00:06:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |     private readonly _element: HTMLElement; | 
					
						
							| 
									
										
										
										
											2020-08-31 02:59:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |     private readonly _value: UIEventSource<T>; | 
					
						
							|  |  |  |     private readonly _values: { value: T; shown: string | BaseUIElement }[]; | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-20 19:35:08 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      *  | 
					
						
							|  |  |  |      * const dropdown = new DropDown<number>("test",[{value: 42, shown: "the answer"}]) | 
					
						
							|  |  |  |      * dropdown.GetValue().data // => 42
 | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |     constructor(label: string | BaseUIElement, | 
					
						
							|  |  |  |                 values: { value: T, shown: string | BaseUIElement }[], | 
					
						
							| 
									
										
										
										
											2021-01-17 21:06:54 +01:00
										 |  |  |                 value: UIEventSource<T> = undefined, | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |                 options?: { | 
					
						
							|  |  |  |                     select_class?: string | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |     ) { | 
					
						
							|  |  |  |         super(); | 
					
						
							| 
									
										
										
										
											2022-07-20 19:35:08 +02:00
										 |  |  |         value = value ?? new UIEventSource<T>(values[0].value) | 
					
						
							| 
									
										
										
										
											2021-06-15 16:18:58 +02:00
										 |  |  |         this._value = value | 
					
						
							| 
									
										
										
										
											2021-06-12 02:58:32 +02:00
										 |  |  |         this._values = values; | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |         if (values.length <= 1) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const id = DropDown._nextDropdownId; | 
					
						
							|  |  |  |         DropDown._nextDropdownId++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const el = document.createElement("form") | 
					
						
							|  |  |  |         this._element = el; | 
					
						
							|  |  |  |         el.id = "dropdown" + id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             const labelEl = Translations.W(label)?.ConstructElement() | 
					
						
							| 
									
										
										
										
											2021-06-12 02:58:32 +02:00
										 |  |  |             if (labelEl !== undefined) { | 
					
						
							|  |  |  |                 const labelHtml = document.createElement("label") | 
					
						
							|  |  |  |                 labelHtml.appendChild(labelEl) | 
					
						
							|  |  |  |                 labelHtml.htmlFor = el.id; | 
					
						
							| 
									
										
										
										
											2021-06-13 15:04:55 +02:00
										 |  |  |                 el.appendChild(labelHtml) | 
					
						
							| 
									
										
										
										
											2021-06-12 02:58:32 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-15 16:18:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 17:42:26 +02:00
										 |  |  |         options = options ?? {} | 
					
						
							| 
									
										
										
										
											2022-04-19 23:43:28 +02:00
										 |  |  |         options.select_class = options.select_class ?? 'w-full bg-indigo-100 p-1 rounded hover:bg-indigo-200' | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             const select = document.createElement("select") | 
					
						
							| 
									
										
										
										
											2021-06-14 17:42:26 +02:00
										 |  |  |             select.classList.add(...(options.select_class.split(" ") ?? [])) | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |             for (let i = 0; i < values.length; i++) { | 
					
						
							|  |  |  |                 const option = document.createElement("option") | 
					
						
							|  |  |  |                 option.value = "" + i | 
					
						
							|  |  |  |                 option.appendChild(Translations.W(values[i].shown).ConstructElement()) | 
					
						
							| 
									
										
										
										
											2021-06-13 15:04:55 +02:00
										 |  |  |                 select.appendChild(option) | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-06-13 15:04:55 +02:00
										 |  |  |             el.appendChild(select) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             select.onchange = (() => { | 
					
						
							| 
									
										
										
										
											2022-07-20 19:35:08 +02:00
										 |  |  |                 const index = select.selectedIndex; | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |                 value.setData(values[index].value); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2021-06-12 02:58:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |             value.addCallbackAndRun(selected => { | 
					
						
							|  |  |  |                 for (let i = 0; i < values.length; i++) { | 
					
						
							|  |  |  |                     const value = values[i].value; | 
					
						
							|  |  |  |                     if (value === selected) { | 
					
						
							|  |  |  |                         select.selectedIndex = i; | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-06-12 02:58:32 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |             }) | 
					
						
							| 
									
										
										
										
											2020-07-21 00:38:03 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.onClick(() => { | 
					
						
							|  |  |  |         }) // by registering a click, the click event is consumed and doesn't bubble further to other elements, e.g. checkboxes
 | 
					
						
							| 
									
										
										
										
											2020-06-28 00:06:23 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |     GetValue(): UIEventSource<T> { | 
					
						
							|  |  |  |         return this._value; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |     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 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |     protected InnerConstructElement(): HTMLElement { | 
					
						
							|  |  |  |         return this._element; | 
					
						
							| 
									
										
										
										
											2020-06-28 00:06:23 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |