Fix numbers got wrecked on blur

Numbers with , as decimal separator were being re-parsed incorrectly on blur, ruining what the user just input
This commit is contained in:
nathan 2024-09-03 15:22:53 -06:00
parent 7298dff322
commit 3e121cc953
4 changed files with 31 additions and 22 deletions

View File

@ -313,7 +313,7 @@ export class Et2DateDuration extends Et2InputWidget(LitElement)
{
for(let i = this._durationNode.length; --i >= 0;)
{
value += parseInt(<string>this._durationNode[i].value) * this._unit2seconds(this._durationNode[i].name);
value += this._durationNode[i].valueAsNumber * this._unit2seconds(this._durationNode[i].name);
}
if(this.dataFormat !== 's')
{

View File

@ -9,7 +9,7 @@
*/
import {Et2Textbox} from "./Et2Textbox";
import {css, html, nothing, render} from "lit";
import {css, html, nothing, PropertyValues, render} from "lit";
import {customElement} from "lit/decorators/custom-element.js";
import {property} from "lit/decorators/property.js";
@ -150,6 +150,10 @@ export class Et2Number extends Et2Textbox
// Add spinners
render(this._incrementButtonTemplate(), this);
if(this.value)
{
this.value = formatNumber(this.value, this.decimalSeparator, this.thousandsSeparator, this.precision);
}
}
firstUpdated()
@ -170,6 +174,14 @@ export class Et2Number extends Et2Textbox
});
}
willUpdate(changedProperties : PropertyValues)
{
if(this._mask && Object.keys(this.maskOptions).filter(v => changedProperties.has(v)).length > 0)
{
this._mask.updateOptions(this.maskOptions);
}
}
transformAttributes(attrs)
{
if(attrs.precision === 0 && typeof attrs.step === 'undefined')
@ -237,7 +249,6 @@ export class Et2Number extends Et2Textbox
val = this.min;
}
super.value = formatNumber(val, this.decimalSeparator, this.thousandsSeparator, this.precision);
this.updateMaskValue();
}
get value() : string
@ -245,6 +256,13 @@ export class Et2Number extends Et2Textbox
return super.value;
}
protected updateMaskValue()
{}
/**
* Value returned to server is always no thousands separator, "." decimal separator
* @returns {any}
*/
getValue() : any
{
if(this.value == "" || typeof this.value == "undefined")
@ -257,8 +275,7 @@ export class Et2Number extends Et2Textbox
get valueAsNumber() : number
{
this.updateMaskValue();
let formattedValue = (this._mask?.value ? this.stripFormat(this._mask.value) : this._mask?.unmaskedValue) ?? this.value;
let formattedValue : string | number = "" + this.stripFormat(this.value);
if(formattedValue == "")
{
return 0;
@ -345,21 +362,6 @@ export class Et2Number extends Et2Textbox
return options;
}
updateMaskValue()
{
this._mask?.updateValue();
if(!this.mask && this._mask)
{
// Number mask sometimes gets lost with different decimal characters
this._mask.unmaskedValue = ("" + this.value);
}
if(this.value !== "" && this._mask)
{
this._mask.value = formatNumber(this.value, this.decimalSeparator, this.thousandsSeparator, this.precision);
}
this._mask?.updateValue();
}
private handleScroll(e)
@ -409,7 +411,7 @@ export class Et2Number extends Et2Textbox
* @param {number} value
* @returns {string}
*/
export function formatNumber(value : number, decimalSeparator : string = ".", thousandsSeparator : string = "", decimalPlaces = undefined) : string
export function formatNumber(value : string | number, decimalSeparator : string = ".", thousandsSeparator : string = "", decimalPlaces = undefined) : string
{
// Split by . because value is a number, so . is decimal separator
let parts = ("" + value).split(".");

View File

@ -202,6 +202,10 @@ export class Et2Textbox extends Et2InputWidget(SlInput)
protected updateMaskValue()
{
if(!this._mask)
{
return;
}
this._mask.unmaskedValue = "" + this.value;
this._mask.updateValue();
this.updateComplete.then(() =>

View File

@ -83,13 +83,14 @@ describe("Number widget", () =>
expected = set;
}
element.value = set;
assert.equal(element.value, expected);
assert.equal(element.getValue(), expected);
};
it("Handles . as decimal", () =>
{
window.egw.preference = () => ".";
element.decimalSeparator = ".";
checkValue("1");
assert.equal(element.valueAsNumber, 1, "Numeric value does not match");
@ -102,10 +103,12 @@ describe("Number widget", () =>
it("Handles , as decimal", () =>
{
window.egw.preference = () => ",";
element.decimalSeparator = ",";
checkValue("1");
assert.equal(element.valueAsNumber, 1, "Numeric value does not match");
checkValue("1,1", "1.1");
assert.equal(element.getValue(), "1.1");
assert.equal(element.valueAsNumber, 1.1, "Numeric value does not match");
element.value = "Fail";