| 
									
										
										
										
											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> { | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |     private static _nextId = 0; | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false); | 
					
						
							| 
									
										
										
										
											2020-09-09 18:42:13 +02:00
										 |  |  |     private readonly value: UIEventSource<T>; | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |     private _elements: InputElement<T>[]; | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |     private _selectFirstAsDefault: boolean; | 
					
						
							| 
									
										
										
										
											2021-01-21 05:52:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     constructor(elements: InputElement<T>[], | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 selectFirstAsDefault = true) { | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |         super() | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |         this._selectFirstAsDefault = selectFirstAsDefault; | 
					
						
							|  |  |  |         this._elements = Utils.NoNull(elements); | 
					
						
							|  |  |  |         this.value = new UIEventSource<T>(undefined) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     protected InnerConstructElement(): HTMLElement { | 
					
						
							|  |  |  |         const elements = this._elements; | 
					
						
							|  |  |  |         const selectFirstAsDefault = this._selectFirstAsDefault; | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |         const selectedElementIndex: UIEventSource<number> = new UIEventSource<number>(null); | 
					
						
							|  |  |  |         const value = | 
					
						
							|  |  |  |             UIEventSource.flatten(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())); | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |         value.syncWith(this.value) | 
					
						
							| 
									
										
										
										
											2021-06-14 17:28:11 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         if(selectFirstAsDefault){ | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |         value.addCallbackAndRun(selected =>{ | 
					
						
							|  |  |  |             if(selected === undefined){ | 
					
						
							|  |  |  |                 for (const element of elements) { | 
					
						
							|  |  |  |                     const v = element.GetValue().data; | 
					
						
							|  |  |  |                     if(v !== undefined){ | 
					
						
							|  |  |  |                         value.setData(v) | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 17:28:11 +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(() => { | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |                 selectedElementIndex.setData(i); | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  |             }); | 
					
						
							| 
									
										
										
										
											2020-09-30 22:48:58 +02:00
										 |  |  |             elements[i].IsSelected.addCallback(isSelected => { | 
					
						
							|  |  |  |                 if (isSelected) { | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |                     selectedElementIndex.setData(i); | 
					
						
							| 
									
										
										
										
											2020-09-30 22:48:58 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							| 
									
										
										
										
											2020-10-17 03:19:14 +02:00
										 |  |  |             elements[i].GetValue().addCallback(() => { | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |                 selectedElementIndex.setData(i); | 
					
						
							| 
									
										
										
										
											2020-10-17 03:19:14 +02:00
										 |  |  |             }) | 
					
						
							| 
									
										
										
										
											2020-07-20 13:28:45 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const groupId = "radiogroup" + RadioButton._nextId | 
					
						
							|  |  |  |         RadioButton._nextId++ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const form = document.createElement("form") | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |         const inputs = [] | 
					
						
							| 
									
										
										
										
											2021-06-19 18:28:30 +02:00
										 |  |  |         const wrappers: HTMLElement[] = [] | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |         for (let i1 = 0; i1 < elements.length; i1++) { | 
					
						
							|  |  |  |             let element = elements[i1]; | 
					
						
							|  |  |  |             const labelHtml = element.ConstructElement(); | 
					
						
							|  |  |  |             if (labelHtml === undefined) { | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             const input = document.createElement("input") | 
					
						
							|  |  |  |             input.id = "radio" + groupId + "-" + i1; | 
					
						
							|  |  |  |             input.name = groupId; | 
					
						
							|  |  |  |             input.type = "radio" | 
					
						
							| 
									
										
										
										
											2021-06-19 18:28:30 +02:00
										 |  |  |                input.classList.add("p-1","cursor-pointer","ml-2","pl-2","pr-0","m-3","mr-0") | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 17:28:11 +02:00
										 |  |  |             input.onchange = () => { | 
					
						
							|  |  |  |                 if(input.checked){ | 
					
						
							|  |  |  |                     selectedElementIndex.setData(i1) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |              | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |             | 
					
						
							|  |  |  |             inputs.push(input) | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             const label = document.createElement("label") | 
					
						
							|  |  |  |             label.appendChild(labelHtml) | 
					
						
							|  |  |  |             label.htmlFor = input.id; | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |             label.classList.add("block","w-full","p-2","cursor-pointer","bg-red") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 17:28:11 +02:00
										 |  |  |             const block = document.createElement("div") | 
					
						
							|  |  |  |             block.appendChild(input) | 
					
						
							|  |  |  |             block.appendChild(label) | 
					
						
							| 
									
										
										
										
											2021-06-19 18:28:30 +02:00
										 |  |  |             block.classList.add("flex","w-full","border", "rounded-full", "border-gray-400","m-1") | 
					
						
							|  |  |  |             wrappers.push(block) | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 17:28:11 +02:00
										 |  |  |             form.appendChild(block) | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-19 18:28:30 +02:00
										 |  |  |         value.addCallbackAndRun( | 
					
						
							|  |  |  |             selected => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 let somethingChecked = false; | 
					
						
							|  |  |  |                 for (let i = 0; i < inputs.length; i++){ | 
					
						
							|  |  |  |                     let input = inputs[i]; | 
					
						
							|  |  |  |                     input.checked = !somethingChecked && elements[i].IsValid(selected); | 
					
						
							|  |  |  |                     somethingChecked = somethingChecked || input.checked | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if(input.checked){ | 
					
						
							|  |  |  |                         wrappers[i].classList.remove("border-gray-400") | 
					
						
							|  |  |  |                         wrappers[i].classList.add("border-black") | 
					
						
							|  |  |  |                     }else{ | 
					
						
							|  |  |  |                         wrappers[i].classList.add("border-gray-400") | 
					
						
							|  |  |  |                         wrappers[i].classList.remove("border-black") | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 17:28:11 +02:00
										 |  |  |         this.SetClass("flex flex-col") | 
					
						
							| 
									
										
										
										
											2021-06-16 21:23:03 +02:00
										 |  |  |         return form; | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |     /* | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-14 02:39:23 +02:00
										 |  |  |     }*/ | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |