forked from MapComplete/MapComplete
		
	Add multi-checkbox component
This commit is contained in:
		
							parent
							
								
									e4bbf9a054
								
							
						
					
					
						commit
						eab842d18a
					
				
					 3 changed files with 138 additions and 5 deletions
				
			
		
							
								
								
									
										113
									
								
								UI/Input/Checkboxes.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								UI/Input/Checkboxes.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,113 @@
 | 
				
			||||||
 | 
					import {InputElement} from "./InputElement";
 | 
				
			||||||
 | 
					import {UIEventSource} from "../../Logic/UIEventSource";
 | 
				
			||||||
 | 
					import {Utils} from "../../Utils";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Supports multi-input
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export class CheckBoxes<T> extends InputElement<T[]> {
 | 
				
			||||||
 | 
					    IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _selectedElementIndex: UIEventSource<number>
 | 
				
			||||||
 | 
					        = new UIEventSource<number>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly value: UIEventSource<T[]>;
 | 
				
			||||||
 | 
					    private readonly _elements: InputElement<T>[]
 | 
				
			||||||
 | 
					    private readonly _selectFirstAsDefault: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(elements: InputElement<T>[],
 | 
				
			||||||
 | 
					                selectFirstAsDefault = true) {
 | 
				
			||||||
 | 
					        super(undefined);
 | 
				
			||||||
 | 
					        this._elements = Utils.NoNull(elements);
 | 
				
			||||||
 | 
					        this._selectFirstAsDefault = selectFirstAsDefault;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.value = new UIEventSource<T[]>([])
 | 
				
			||||||
 | 
					        this.ListenTo(this.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IsValid(ts: T[]): boolean {
 | 
				
			||||||
 | 
					        if (ts === undefined) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (const t of ts) {
 | 
				
			||||||
 | 
					            let matchFound = false;
 | 
				
			||||||
 | 
					            for (const element of this._elements) {
 | 
				
			||||||
 | 
					                if (element.IsValid(t)) {
 | 
				
			||||||
 | 
					                    matchFound = true;
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (!matchFound) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GetValue(): UIEventSource<T[]> {
 | 
				
			||||||
 | 
					        return this.value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private IdFor(i) {
 | 
				
			||||||
 | 
					        return 'checkmark-' + this.id + '-' + i;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    InnerRender(): string {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let body = "";
 | 
				
			||||||
 | 
					        for (let i = 0; i < this._elements.length; i++) {
 | 
				
			||||||
 | 
					            let el = this._elements[i];
 | 
				
			||||||
 | 
					            const htmlElement =
 | 
				
			||||||
 | 
					                `<input type="checkbox" id="${this.IdFor(i)}"><label for="${this.IdFor(i)}">${el.Render()}</label><br/>`;
 | 
				
			||||||
 | 
					            body += htmlElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return `<form id='${this.id}-form'>${body}</form>`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected InnerUpdate(htmlElement: HTMLElement) {
 | 
				
			||||||
 | 
					        super.InnerUpdate(htmlElement);
 | 
				
			||||||
 | 
					        const self = this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (let i = 0; i < this._elements.length; i++) {
 | 
				
			||||||
 | 
					            const el = document.getElementById(this.IdFor(i));
 | 
				
			||||||
 | 
					            const inputEl = this._elements[i];
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                const v = inputEl.GetValue().data;
 | 
				
			||||||
 | 
					                const index = self.value.data.indexOf(v);
 | 
				
			||||||
 | 
					                if(index >= 0){
 | 
				
			||||||
 | 
					                    // @ts-ignore
 | 
				
			||||||
 | 
					                    el.checked = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            el.onchange = e => {
 | 
				
			||||||
 | 
					                const v = inputEl.GetValue().data;
 | 
				
			||||||
 | 
					                const index = self.value.data.indexOf(v);
 | 
				
			||||||
 | 
					                // @ts-ignore
 | 
				
			||||||
 | 
					                if (el.checked) {
 | 
				
			||||||
 | 
					                    if (index < 0) {
 | 
				
			||||||
 | 
					                        self.value.data.push(v);
 | 
				
			||||||
 | 
					                        self.value.ping();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    if (index >= 0) {
 | 
				
			||||||
 | 
					                        self.value.data.splice(index, 1);
 | 
				
			||||||
 | 
					                        self.value.ping();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,6 @@ export class RadioButton<T> extends InputElement<T> {
 | 
				
			||||||
    constructor(elements: InputElement<T>[],
 | 
					    constructor(elements: InputElement<T>[],
 | 
				
			||||||
                selectFirstAsDefault = true) {
 | 
					                selectFirstAsDefault = true) {
 | 
				
			||||||
        super(undefined);
 | 
					        super(undefined);
 | 
				
			||||||
        console.log("Created new radiobutton with values ", elements)
 | 
					 | 
				
			||||||
        this._elements = Utils.NoNull(elements);
 | 
					        this._elements = Utils.NoNull(elements);
 | 
				
			||||||
        this._selectFirstAsDefault = selectFirstAsDefault;
 | 
					        this._selectFirstAsDefault = selectFirstAsDefault;
 | 
				
			||||||
        const self = this;
 | 
					        const self = this;
 | 
				
			||||||
| 
						 | 
					@ -66,15 +65,14 @@ export class RadioButton<T> extends InputElement<T> {
 | 
				
			||||||
    InnerRender(): string {
 | 
					    InnerRender(): string {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let body = "";
 | 
					        let body = "";
 | 
				
			||||||
        let i = 0;
 | 
					        for (let i = 0; i < this._elements.length; i++){
 | 
				
			||||||
        for (const el of this._elements) {
 | 
					            const el = this._elements[i];
 | 
				
			||||||
            const htmlElement =
 | 
					            const htmlElement =
 | 
				
			||||||
                '<input type="radio" id="' + this.IdFor(i) + '" name="radiogroup-' + this.id + '">' +
 | 
					                '<input type="radio" id="' + this.IdFor(i) + '" name="radiogroup-' + this.id + '">' +
 | 
				
			||||||
                '<label for="' + this.IdFor(i) + '">' + el.Render() + '</label>' +
 | 
					                '<label for="' + this.IdFor(i) + '">' + el.Render() + '</label>' +
 | 
				
			||||||
                '<br>';
 | 
					                '<br>';
 | 
				
			||||||
            body += htmlElement;
 | 
					            body += htmlElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            i++;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return "<form id='" + this.id + "-form'>" + body + "</form>";
 | 
					        return "<form id='" + this.id + "-form'>" + body + "</form>";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										24
									
								
								test.ts
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								test.ts
									
										
									
									
									
								
							| 
						 | 
					@ -1,4 +1,26 @@
 | 
				
			||||||
import BikeCafes from "./Customizations/Layers/BikeCafes";
 | 
					import BikeCafes from "./Customizations/Layers/BikeCafes";
 | 
				
			||||||
 | 
					import {CheckBoxes} from "./UI/Input/Checkboxes";
 | 
				
			||||||
 | 
					import {FixedInputElement} from "./UI/Input/FixedInputElement";
 | 
				
			||||||
 | 
					import {VariableUiElement} from "./UI/Base/VariableUIElement";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
console.log(JSON.stringify(new BikeCafes()))
 | 
					const cb = new CheckBoxes(
 | 
				
			||||||
 | 
					   [ new FixedInputElement("One", 1),
 | 
				
			||||||
 | 
					   new FixedInputElement("Two",2),
 | 
				
			||||||
 | 
					   new FixedInputElement("Thee",3)]
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cb.AttachTo("maindiv");
 | 
				
			||||||
 | 
					new VariableUiElement(cb.GetValue().map(ts => ts?.join(", "))).AttachTo("extradiv")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.setTimeout(() => {
 | 
				
			||||||
 | 
					   cb.GetValue().setData([2,3]);
 | 
				
			||||||
 | 
					}, 2500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.setTimeout(() => {
 | 
				
			||||||
 | 
					   cb.GetValue().setData([2]);
 | 
				
			||||||
 | 
					}, 3000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.setTimeout(() => {
 | 
				
			||||||
 | 
					   cb.GetValue().setData([1, 2]);
 | 
				
			||||||
 | 
					}, 3500)
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue