forked from MapComplete/MapComplete
		
	Huge refactorings of JSON-parsing and Tagsfilter, other cleanups, warning cleanups and lots of small subtle bugfixes
This commit is contained in:
		
							parent
							
								
									9a5b35b9f3
								
							
						
					
					
						commit
						a57b7d93fa
					
				
					 113 changed files with 1565 additions and 2594 deletions
				
			
		|  | @ -4,16 +4,13 @@ import Translations from "../i18n/Translations"; | |||
| import {UIEventSource} from "../../Logic/UIEventSource"; | ||||
| import * as EmailValidator from "email-validator"; | ||||
| import {parsePhoneNumberFromString} from "libphonenumber-js"; | ||||
| import {TagRenderingOptions} from "../../Customizations/TagRenderingOptions"; | ||||
| import {CustomLayoutFromJSON} from "../../Customizations/JSON/CustomLayoutFromJSON"; | ||||
| import {And, Tag} from "../../Logic/TagsFilter"; | ||||
| 
 | ||||
| export class ValidatedTextField { | ||||
|     public static inputValidation = { | ||||
|         "$": (str) => true, | ||||
|         "string": (str) => true, | ||||
|         "date": (str) => true, // TODO validate and add a date picker
 | ||||
|         "wikidata": (str) => true, // TODO validate wikidata IDS
 | ||||
|         "$": () => true, | ||||
|         "string": () => true, | ||||
|         "date": () => true, // TODO validate and add a date picker
 | ||||
|         "wikidata": () => true, // TODO validate wikidata IDS
 | ||||
|         "int": (str) => {str = ""+str; return str !== undefined && str.indexOf(".") < 0 && !isNaN(Number(str))}, | ||||
|         "nat": (str) => {str = ""+str; return str !== undefined && str.indexOf(".") < 0 && !isNaN(Number(str)) && Number(str) > 0}, | ||||
|         "float": (str) => !isNaN(Number(str)), | ||||
|  | @ -31,75 +28,18 @@ export class ValidatedTextField { | |||
|             return parsePhoneNumberFromString(str, country.toUpperCase()).formatInternational() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static TagTextField(value: UIEventSource<Tag[]> = undefined, allowEmpty: boolean) { | ||||
|         allowEmpty = allowEmpty ?? false; | ||||
|         return new TextField<Tag[]>({ | ||||
|                 placeholder: "Tags", | ||||
|                 fromString: str => { | ||||
|                     const tags = CustomLayoutFromJSON.TagsFromJson(str); | ||||
|                     console.log("Parsed",str," --> ",tags) | ||||
|                     if (tags === []) { | ||||
|                         if (allowEmpty) { | ||||
|                             return [] | ||||
|                         } else { | ||||
|                             return undefined; | ||||
|                         } | ||||
|                     } | ||||
|                     return tags; | ||||
|                 } | ||||
|                 , | ||||
|                 toString: (tags: Tag[]) => { | ||||
|                     if (tags === undefined || tags === []) { | ||||
|                         if (allowEmpty) { | ||||
|                             return ""; | ||||
|                         } else { | ||||
|                             return undefined; | ||||
|                         } | ||||
|                     } | ||||
|                     return new And(tags).asHumanString(false, false); | ||||
|                 }, | ||||
|                 value: value, | ||||
|                 startValidated: true | ||||
|             } | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     public static | ||||
| 
 | ||||
|     ValidatedTextField(type: string, options: { value?: UIEventSource<string>, country?: string }) | ||||
|         : TextField<string> { | ||||
|         let isValid = ValidatedTextField.inputValidation[type]; | ||||
|         if (isValid === undefined | ||||
|         ) { | ||||
|             throw "Invalid type for textfield: " + type | ||||
|         } | ||||
|         let formatter = ValidatedTextField.formatting[type] ?? ((str) => str); | ||||
|         return new TextField<string>({ | ||||
|             placeholder: type, | ||||
|             toString: str => str, | ||||
|             fromString: str => isValid(str, options?.country) ? formatter(str, options.country) : undefined, | ||||
|             value: options.value, | ||||
|             startValidated: true | ||||
|         }) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| export class TextField<T> extends InputElement<T> { | ||||
| 
 | ||||
| 
 | ||||
|     private value: UIEventSource<string>; | ||||
|     private mappedValue: UIEventSource<T>; | ||||
|     /** | ||||
|      * Pings and has the value data | ||||
|      */ | ||||
|     public enterPressed = new UIEventSource<string>(undefined); | ||||
|     private _placeholder: UIElement; | ||||
|     private _fromString?: (string: string) => T; | ||||
|     private _toString: (t: T) => string; | ||||
|     private startValidated: boolean; | ||||
|     private readonly value: UIEventSource<string>; | ||||
|     private readonly mappedValue: UIEventSource<T>; | ||||
|     public readonly enterPressed = new UIEventSource<string>(undefined); | ||||
|     private readonly _placeholder: UIElement; | ||||
|     private readonly _fromString?: (string: string) => T; | ||||
|     private readonly _toString: (t: T) => string; | ||||
|     private readonly startValidated: boolean; | ||||
| 
 | ||||
| 
 | ||||
|     constructor(options: { | ||||
|  | @ -157,14 +97,6 @@ export class TextField<T> extends InputElement<T> { | |||
|     GetValue(): UIEventSource<T> { | ||||
|         return this.mappedValue; | ||||
|     } | ||||
| 
 | ||||
|     ShowValue(t: T): boolean { | ||||
|         if (!this.IsValid(t)) { | ||||
|             return false; | ||||
|         } | ||||
|         this.mappedValue.setData(t); | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|         return `<form onSubmit='return false' class='form-text-field'>` + | ||||
|             `<input type='text' placeholder='${this._placeholder.InnerRender()}' id='text-${this.id}'>` + | ||||
|  | @ -178,7 +110,7 @@ export class TextField<T> extends InputElement<T> { | |||
|         } | ||||
| 
 | ||||
|         this.mappedValue.addCallback((data) => { | ||||
|             field.className = this.mappedValue.data !== undefined ? "valid" : "invalid"; | ||||
|             field.className = data !== undefined ? "valid" : "invalid"; | ||||
|         }); | ||||
|          | ||||
|         field.className = this.mappedValue.data !== undefined ? "valid" : "invalid"; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue