Improve input of values with units: add indicator of denomination if only one is defined, stabilize reformatting

This commit is contained in:
Pieter Vander Vennet 2021-09-13 01:17:48 +02:00
parent 68728e18f3
commit 21448a6fea

View file

@ -15,6 +15,7 @@ import BaseUIElement from "../BaseUIElement";
import LengthInput from "./LengthInput"; import LengthInput from "./LengthInput";
import {GeoOperations} from "../../Logic/GeoOperations"; import {GeoOperations} from "../../Logic/GeoOperations";
import {Unit} from "../../Models/Unit"; import {Unit} from "../../Models/Unit";
import {FixedInputElement} from "./FixedInputElement";
interface TextFieldDef { interface TextFieldDef {
name: string, name: string,
@ -197,14 +198,14 @@ export default class ValidatedTextField {
ValidatedTextField.tp( ValidatedTextField.tp(
"float", "float",
"A decimal", "A decimal",
(str) => !isNaN(Number(str)), (str) => !isNaN(Number(str)) && !str.endsWith(".") && !str.endsWith(","),
str => "" + Number(str), str => "" + Number(str),
undefined, undefined,
"decimal"), "decimal"),
ValidatedTextField.tp( ValidatedTextField.tp(
"pfloat", "pfloat",
"A positive decimal (incl zero)", "A positive decimal (incl zero)",
(str) => !isNaN(Number(str)) && Number(str) >= 0, (str) => !isNaN(Number(str)) && Number(str) >= 0 && !str.endsWith(".") && !str.endsWith(","),
str => "" + Number(str), str => "" + Number(str),
undefined, undefined,
"decimal"), "decimal"),
@ -323,10 +324,29 @@ export default class ValidatedTextField {
} else { } else {
isValid = isValidTp; isValid = isValidTp;
} }
options.isValid = isValid;
if (options.unit !== undefined && isValid !== undefined) {
// Reformatting is handled by the unit in this case
options.isValid = str => {
const denom = options.unit.findDenomination(str);
if (denom === undefined) {
return false;
}
const stripped = denom[0]
console.log("Is valid? ", str, "stripped: ", stripped, "isValid:", isValid(stripped))
return isValid(stripped)
}
} else {
options.isValid = isValid;
}
options.inputMode = tp.inputmode; options.inputMode = tp.inputmode;
let input: InputElement<string> = new TextField(options); let input: InputElement<string> = new TextField(options);
if (tp.reformat) { if (tp.reformat && options.unit === undefined) {
input.GetValue().addCallbackAndRun(str => { input.GetValue().addCallbackAndRun(str => {
if (!options.isValid(str, options.country)) { if (!options.isValid(str, options.country)) {
return; return;
@ -341,32 +361,42 @@ export default class ValidatedTextField {
// This implies: // This implies:
// We have to create a dropdown with applicable denominations, and fuse those values // We have to create a dropdown with applicable denominations, and fuse those values
const unit = options.unit const unit = options.unit
const unitDropDown = new DropDown("",
unit.denominations.map(denom => { const unitDropDown =
return { unit.denominations.length === 1 ?
shown: denom.human, new FixedInputElement(unit.denominations[0].human, unit.denominations[0])
value: denom : new DropDown("",
} unit.denominations.map(denom => {
}) return {
) shown: denom.human,
value: denom
}
})
)
unitDropDown.GetValue().setData(unit.defaultDenom) unitDropDown.GetValue().setData(unit.defaultDenom)
unitDropDown.SetClass("w-min") unitDropDown.SetClass("w-min")
const fixedDenom = unit.denominations.length === 1 ? unit.denominations[0] : undefined
input = new CombinedInputElement( input = new CombinedInputElement(
input, input,
unitDropDown, unitDropDown,
// combine the value from the textfield and the dropdown into the resulting value that should go into OSM // combine the value from the textfield and the dropdown into the resulting value that should go into OSM
(text, denom) => denom?.canonicalValue(text, true) ?? undefined, (text, denom) => {
if(denom === undefined){
return text
}
return denom?.canonicalValue(text, true)
},
(valueWithDenom: string) => { (valueWithDenom: string) => {
// Take the value from OSM and feed it into the textfield and the dropdown // Take the value from OSM and feed it into the textfield and the dropdown
const withDenom = unit.findDenomination(valueWithDenom); const withDenom = unit.findDenomination(valueWithDenom);
if (withDenom === undefined) { if (withDenom === undefined) {
// Not a valid value at all - we give it undefined and leave the details up to the other elements // Not a valid value at all - we give it undefined and leave the details up to the other elements (but we keep the previous denomination)
return [undefined, undefined] return [undefined, fixedDenom]
} }
const [strippedText, denom] = withDenom const [strippedText, denom] = withDenom
if (strippedText === undefined) { if (strippedText === undefined) {
return [undefined, undefined] return [undefined, fixedDenom]
} }
return [strippedText, denom] return [strippedText, denom]
} }