forked from MapComplete/MapComplete
		
	Finishing refactoring
This commit is contained in:
		
							parent
							
								
									8026e99824
								
							
						
					
					
						commit
						00d95c4be1
					
				
					 8 changed files with 86 additions and 57 deletions
				
			
		|  | @ -263,7 +263,7 @@ class TagRendering extends UIElement implements TagDependantUIElement { | ||||||
|             this._editButton = new FixedUiElement("<img class='editbutton' src='./assets/pencil.svg' alt='edit'>") |             this._editButton = new FixedUiElement("<img class='editbutton' src='./assets/pencil.svg' alt='edit'>") | ||||||
|                 .onClick(() => { |                 .onClick(() => { | ||||||
|                     self._editMode.setData(true); |                     self._editMode.setData(true); | ||||||
|                     self._questionElement.ShowValue(self.CurrentValue()); |                     self._questionElement.GetValue().setData(self.CurrentValue()); | ||||||
|                 }); |                 }); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ export class ImageUploadFlow extends UIElement { | ||||||
|             preferedLicense |             preferedLicense | ||||||
|         ); |         ); | ||||||
|         this._licensePicker = licensePicker; |         this._licensePicker = licensePicker; | ||||||
|         this._selectedLicence = licensePicker.selectedElement; |         this._selectedLicence = licensePicker.GetValue(); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         const licenseExplanations = { |         const licenseExplanations = { | ||||||
|  | @ -62,7 +62,7 @@ export class ImageUploadFlow extends UIElement { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     protected InnerRender(): string { |     InnerRender(): string { | ||||||
| 
 | 
 | ||||||
|         if (!this._userdetails.data.loggedIn) { |         if (!this._userdetails.data.loggedIn) { | ||||||
|             return "<div class='activate-osm-authentication'>Gelieve je aan te melden om een foto toe te voegen of vragen te beantwoorden</div>"; |             return "<div class='activate-osm-authentication'>Gelieve je aan te melden om een foto toe te voegen of vragen te beantwoorden</div>"; | ||||||
|  |  | ||||||
|  | @ -1,35 +1,61 @@ | ||||||
| import {UIEventSource} from "../UIEventSource"; | import {UIEventSource} from "../UIEventSource"; | ||||||
| import {UIElement} from "../UIElement"; | import {UIElement} from "../UIElement"; | ||||||
|  | import {InputElement} from "./InputElement"; | ||||||
|  | import instantiate = WebAssembly.instantiate; | ||||||
|  | import {FixedUiElement} from "../Base/FixedUiElement"; | ||||||
| 
 | 
 | ||||||
| export class DropDown extends UIElement { | export class DropDown<T> extends InputElement<T> { | ||||||
| 
 | 
 | ||||||
|     selectedElement: UIEventSource<string> |     private readonly _label: string; | ||||||
|     private _label: string; |     private readonly _values: { value: T; shown: UIElement }[]; | ||||||
|     private _values: { value: string; shown: string }[]; |  | ||||||
| 
 | 
 | ||||||
|     constructor(label: string, values: { value: string, shown: string }[], |     private readonly _value; | ||||||
|                 selectedElement: UIEventSource<string> = undefined) { | 
 | ||||||
|  |     constructor(label: string, | ||||||
|  |                 values: { value: T, shown: string | UIElement }[], | ||||||
|  |                 value: UIEventSource<T> = undefined) { | ||||||
|         super(undefined); |         super(undefined); | ||||||
|  |         this._value = value ?? new UIEventSource<T>(undefined); | ||||||
|         this._label = label; |         this._label = label; | ||||||
|         this._values = values; |         this._values = values.map(v => { | ||||||
|         this.selectedElement = selectedElement ?? new UIEventSource<string>(values[0].value); |                 return { | ||||||
|         if(selectedElement.data === undefined){ |                     value: v.value, | ||||||
|             this.selectedElement.setData(values[0].value) |                     shown: v.shown instanceof UIElement ? v.shown : new FixedUiElement(v.shown) | ||||||
|                 } |                 } | ||||||
|         const self = this; |             } | ||||||
|         this.selectedElement.addCallback(() => { |         ); | ||||||
|             self.InnerUpdate(); |         this.ListenTo(this._value) | ||||||
|         }); | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     GetValue(): UIEventSource<T> { | ||||||
|  |         return this._value; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ShowValue(t: T): boolean { | ||||||
|  |         if (!this.IsValid(t)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         this._value.setData(t); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IsValid(t: T): boolean { | ||||||
|  |         for (const value of this._values) { | ||||||
|  |             if (value.value === t) { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return false | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     protected InnerRender(): string { |     InnerRender(): string { | ||||||
| 
 | 
 | ||||||
|         let options = ""; |         let options = ""; | ||||||
|         for (const value of this._values) { |         for (let i = 0; i < this._values.length; i++) { | ||||||
|             options += "<option value='" + value.value + "'>" + value.shown + "</option>" |             options += "<option value='" + i + "'>" + this._values[i].shown.InnerRender() + "</option>" | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|  |         } | ||||||
|         return "<form>" + |         return "<form>" + | ||||||
|             "<label for='dropdown-" + this.id + "'>" + this._label + "</label>" + |             "<label for='dropdown-" + this.id + "'>" + this._label + "</label>" + | ||||||
|             "<select name='dropdown-" + this.id + "' id='dropdown-" + this.id + "'>" + |             "<select name='dropdown-" + this.id + "' id='dropdown-" + this.id + "'>" + | ||||||
|  | @ -38,22 +64,24 @@ export class DropDown extends UIElement { | ||||||
|             "</form>"; |             "</form>"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     InnerUpdate() { |     protected InnerUpdate(element) { | ||||||
|  | 
 | ||||||
|  |         var e = document.getElementById("dropdown-" + this.id); | ||||||
|         const self = this; |         const self = this; | ||||||
|         const e = document.getElementById("dropdown-" + this.id); |         e.onchange = (() => { | ||||||
|         if(e === null){ |             // @ts-ignore
 | ||||||
|             return; |             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++) { | ||||||
|  |             const value = this._values[i]; | ||||||
|  |             if (value.value == t) { | ||||||
|  |                 // @ts-ignore
 | ||||||
|  |                 e.selectedIndex = i; | ||||||
|             } |             } | ||||||
|         // @ts-ignore
 |  | ||||||
|         if (this.selectedElement.data !== e.value) { |  | ||||||
|             // @ts-ignore
 |  | ||||||
|             e.value = this.selectedElement.data; |  | ||||||
|         } |  | ||||||
|         e.onchange = function () { |  | ||||||
|             // @ts-ignore
 |  | ||||||
|             const selectedValue = e.options[e.selectedIndex].value; |  | ||||||
|             console.log("Putting data", selectedValue) |  | ||||||
|             self.selectedElement.setData(selectedValue); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -8,6 +8,4 @@ export abstract class InputElement<T> extends UIElement{ | ||||||
|      |      | ||||||
|     abstract IsValid(t: T) : boolean; |     abstract IsValid(t: T) : boolean; | ||||||
|      |      | ||||||
|     abstract ShowValue(t: T) : boolean; |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | @ -27,8 +27,7 @@ export class RadioButton<T> extends InputElement<T> { | ||||||
|                         return elements[selectedIndex].GetValue() |                         return elements[selectedIndex].GetValue() | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             ), elements.map(e => e.GetValue())) |             ), elements.map(e => e.GetValue())); | ||||||
|         ; |  | ||||||
| 
 | 
 | ||||||
|         this.value.addCallback((t) => { |         this.value.addCallback((t) => { | ||||||
|             self.ShowValue(t); |             self.ShowValue(t); | ||||||
|  |  | ||||||
|  | @ -23,9 +23,11 @@ export class TextField<T> extends InputElement<T> { | ||||||
|         value?: UIEventSource<T> |         value?: UIEventSource<T> | ||||||
|     }) { |     }) { | ||||||
|         super(undefined); |         super(undefined); | ||||||
|  |         const self = this; | ||||||
|         this.value = new UIEventSource<string>(""); |         this.value = new UIEventSource<string>(""); | ||||||
|         this.mappedValue = options?.value ?? new UIEventSource<T>(undefined); |  | ||||||
| 
 | 
 | ||||||
|  |         this.mappedValue = options?.value ?? new UIEventSource<T>(undefined); | ||||||
|  |         this.mappedValue.addCallback(() => self.InnerUpdate()); | ||||||
| 
 | 
 | ||||||
|         // @ts-ignore
 |         // @ts-ignore
 | ||||||
|         this._fromString = options.fromString ?? ((str) => (str)) |         this._fromString = options.fromString ?? ((str) => (str)) | ||||||
|  | @ -42,7 +44,6 @@ export class TextField<T> extends InputElement<T> { | ||||||
|         this._toString = options.toString ?? ((t) => ("" + t)); |         this._toString = options.toString ?? ((t) => ("" + t)); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         const self = this; |  | ||||||
|         this.mappedValue.addCallback((t) => { |         this.mappedValue.addCallback((t) => { | ||||||
|             if (t === undefined || t === null) { |             if (t === undefined || t === null) { | ||||||
|                 return; |                 return; | ||||||
|  | @ -73,7 +74,7 @@ export class TextField<T> extends InputElement<T> { | ||||||
|             "</form>"; |             "</form>"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     InnerUpdate(htmlElement: HTMLElement) { |     InnerUpdate() { | ||||||
|         const field = document.getElementById('text-' + this.id); |         const field = document.getElementById('text-' + this.id); | ||||||
|         if (field === null) { |         if (field === null) { | ||||||
|             return; |             return; | ||||||
|  | @ -92,8 +93,12 @@ export class TextField<T> extends InputElement<T> { | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         if (this.IsValid(this.mappedValue.data)) { |         if (this.IsValid(this.mappedValue.data)) { | ||||||
|  |             const expected = this._toString(this.mappedValue.data); | ||||||
|             // @ts-ignore
 |             // @ts-ignore
 | ||||||
|             field.value = this._toString(this.mappedValue.data); |             if (field.value !== expected) { | ||||||
|  |                 // @ts-ignore
 | ||||||
|  |                 field.value = expected; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -83,7 +83,8 @@ export abstract class UIElement { | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Called after the HTML has been replaced. Can be used for css tricks
 |     // Called after the HTML has been replaced. Can be used for css tricks
 | ||||||
|     InnerUpdate(htmlElement : HTMLElement){} |    protected InnerUpdate(htmlElement: HTMLElement) { | ||||||
|  |    } | ||||||
| 
 | 
 | ||||||
|     Render(): string { |     Render(): string { | ||||||
|         return "<span class='uielement' id='" + this.id + "'>" + this.InnerRender() + "</span>" |         return "<span class='uielement' id='" + this.id + "'>" + this.InnerRender() + "</span>" | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								test.ts
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								test.ts
									
										
									
									
									
								
							|  | @ -10,17 +10,15 @@ import {VariableUiElement} from "./UI/Base/VariableUIElement"; | ||||||
| import {TextField} from "./UI/Input/TextField"; | import {TextField} from "./UI/Input/TextField"; | ||||||
| import {FixedInputElement} from "./UI/Input/FixedInputElement"; | import {FixedInputElement} from "./UI/Input/FixedInputElement"; | ||||||
| import {RadioButton} from "./UI/Input/RadioButton"; | import {RadioButton} from "./UI/Input/RadioButton"; | ||||||
|  | import {DropDown} from "./UI/Input/DropDown"; | ||||||
|  | import {FixedUiElement} from "./UI/Base/FixedUiElement"; | ||||||
| 
 | 
 | ||||||
| 
 | const dropdown = new RadioButton<string>( | ||||||
| const buttons = new RadioButton<number>( |     [new FixedInputElement("5","5"), | ||||||
|     [new FixedInputElement("Five", 5), |     new TextField({ | ||||||
|         new FixedInputElement("Ten", 10), |         toString: ((str) => str), | ||||||
|         new TextField<number>({ |         fromString: ((str) => str), | ||||||
|             fromString: (str) => parseInt(str), |     })] | ||||||
|             toString: (i) => ("" + i), |  | ||||||
|         }) |  | ||||||
|     ], false |  | ||||||
| ).AttachTo("maindiv"); | ).AttachTo("maindiv"); | ||||||
| 
 | const value = dropdown.GetValue(); | ||||||
| 
 | value.setData("asldkjvmqlksjdf") | ||||||
| buttons.GetValue().addCallback(console.log); |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue