| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | import {InputElement} from "./InputElement"; | 
					
						
							| 
									
										
										
										
											2020-08-17 17:23:15 +02:00
										 |  |  | import {UIEventSource} from "../../Logic/UIEventSource"; | 
					
						
							| 
									
										
										
										
											2020-09-03 00:00:37 +02:00
										 |  |  | import {Utils} from "../../Utils"; | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | export class RadioButton<T> extends InputElement<T> { | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false); | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     private readonly _selectedElementIndex: UIEventSource<number> | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         = new UIEventSource<number>(null); | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 18:42:13 +02:00
										 |  |  |     private readonly value: UIEventSource<T>; | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     private readonly _elements: InputElement<T>[] | 
					
						
							| 
									
										
										
										
											2020-09-09 18:42:13 +02:00
										 |  |  |     private readonly _selectFirstAsDefault: boolean; | 
					
						
							| 
									
										
										
										
											2020-09-26 01:10:10 +02:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     constructor(elements: InputElement<T>[], | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 selectFirstAsDefault = true) { | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  |         super(undefined); | 
					
						
							| 
									
										
										
										
											2020-09-03 00:00:37 +02:00
										 |  |  |         this._elements = Utils.NoNull(elements); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         this._selectFirstAsDefault = selectFirstAsDefault; | 
					
						
							|  |  |  |         const self = this; | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.value = | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |             UIEventSource.flatten(this._selectedElementIndex.map( | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  |                 (selectedIndex) => { | 
					
						
							|  |  |  |                     if (selectedIndex !== undefined && selectedIndex !== null) { | 
					
						
							|  |  |  |                         return elements[selectedIndex].GetValue() | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |             ), elements.map(e => e?.GetValue())); | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         this.value.addCallback((t) => { | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |             self?.ShowValue(t); | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         for (let i = 0; i < elements.length; i++) { | 
					
						
							|  |  |  |             // If an element is clicked, the radio button corresponding with it should be selected as well
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |             elements[i]?.onClick(() => { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                 self._selectedElementIndex.setData(i); | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     IsValid(t: T): boolean { | 
					
						
							|  |  |  |         for (const inputElement of this._elements) { | 
					
						
							|  |  |  |             if (inputElement.IsValid(t)) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     GetValue(): UIEventSource<T> { | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  |         return this.value; | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |     private IdFor(i) { | 
					
						
							|  |  |  |         return 'radio-' + this.id + '-' + i; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |     InnerRender(): string { | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let body = ""; | 
					
						
							| 
									
										
										
										
											2020-09-09 22:17:46 +02:00
										 |  |  |         for (let i = 0; i < this._elements.length; i++){ | 
					
						
							|  |  |  |             const el = this._elements[i]; | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |             const htmlElement = | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 '<input type="radio" id="' + this.IdFor(i) + '" name="radiogroup-' + this.id + '">' + | 
					
						
							|  |  |  |                 '<label for="' + this.IdFor(i) + '">' + el.Render() + '</label>' + | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |                 '<br>'; | 
					
						
							|  |  |  |             body += htmlElement; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return "<form id='" + this.id + "-form'>" + body + "</form>"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 21:03:55 +02:00
										 |  |  |     public ShowValue(t: T): boolean { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         if (t === undefined) { | 
					
						
							| 
									
										
										
										
											2020-07-20 21:03:55 +02:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!this.IsValid(t)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         // We check that what is selected matches the previous rendering
 | 
					
						
							|  |  |  |         for (let i = 0; i < this._elements.length; i++) { | 
					
						
							|  |  |  |             const e = this._elements[i]; | 
					
						
							|  |  |  |             if (e.IsValid(t)) { | 
					
						
							|  |  |  |                 this._selectedElementIndex.setData(i); | 
					
						
							|  |  |  |                 e.GetValue().setData(t); | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |                 const radio = document.getElementById(this.IdFor(i)); | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                 // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |                 radio?.checked = true; | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |     InnerUpdate(htmlElement: HTMLElement) { | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function checkButtons() { | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  |             for (let i = 0; i < self._elements.length; i++) { | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |                 const el = document.getElementById(self.IdFor(i)); | 
					
						
							|  |  |  |                 // @ts-ignore
 | 
					
						
							|  |  |  |                 if (el.checked) { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                     self._selectedElementIndex.setData(i); | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const el = document.getElementById(this.id); | 
					
						
							|  |  |  |         el.addEventListener("change", | 
					
						
							|  |  |  |             function () { | 
					
						
							|  |  |  |                 checkButtons(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2020-07-20 21:03:55 +02:00
										 |  |  |         if (this._selectedElementIndex.data !== null) { | 
					
						
							|  |  |  |             const el = document.getElementById(this.IdFor(this._selectedElementIndex.data)); | 
					
						
							|  |  |  |             if (el) { | 
					
						
							|  |  |  |                 // @ts-ignore
 | 
					
						
							|  |  |  |                 el.checked = true; | 
					
						
							|  |  |  |                 checkButtons(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else if (this._selectFirstAsDefault) { | 
					
						
							|  |  |  |             this.ShowValue(this.value.data); | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |             if (this._selectedElementIndex.data === null || this._selectedElementIndex.data === undefined) { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 const el = document.getElementById(this.IdFor(0)); | 
					
						
							| 
									
										
										
										
											2020-07-08 16:07:16 +02:00
										 |  |  |                 if (el) { | 
					
						
							|  |  |  |                     // @ts-ignore
 | 
					
						
							|  |  |  |                     el.checked = true; | 
					
						
							|  |  |  |                     checkButtons(); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |