| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import { InputElement } from "./InputElement" | 
					
						
							|  |  |  | import Translations from "../i18n/Translations" | 
					
						
							|  |  |  | import { UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							|  |  |  | 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> { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static _nextDropdownId = 0 | 
					
						
							|  |  |  |     public IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false) | 
					
						
							| 
									
										
										
										
											2020-06-28 00:06:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private readonly _element: HTMLElement | 
					
						
							| 
									
										
										
										
											2020-06-28 00:06:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +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
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +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
 | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     constructor( | 
					
						
							|  |  |  |         label: string | BaseUIElement, | 
					
						
							|  |  |  |         values: { value: T; shown: string | BaseUIElement }[], | 
					
						
							|  |  |  |         value: UIEventSource<T> = undefined, | 
					
						
							|  |  |  |         options?: { | 
					
						
							|  |  |  |             select_class?: string | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +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 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this._values = values | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |         if (values.length <= 1) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const id = DropDown._nextDropdownId | 
					
						
							|  |  |  |         DropDown._nextDropdownId++ | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const el = document.createElement("form") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this._element = el | 
					
						
							|  |  |  |         el.id = "dropdown" + id | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 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-09-08 21:40:48 +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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             select.onchange = () => { | 
					
						
							|  |  |  |                 const index = select.selectedIndex | 
					
						
							|  |  |  |                 value.setData(values[index].value) | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             value.addCallbackAndRun((selected) => { | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |                 for (let i = 0; i < values.length; i++) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     const value = values[i].value | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |                     if (value === selected) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         select.selectedIndex = i | 
					
						
							| 
									
										
										
										
											2021-06-10 01:36:20 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +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> { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return this._value | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return true | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											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 { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return this._element | 
					
						
							| 
									
										
										
										
											2020-06-28 00:06:23 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |