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;) 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') if(this.dataFormat !== 's')
{ {

View File

@ -9,7 +9,7 @@
*/ */
import {Et2Textbox} from "./Et2Textbox"; 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 {customElement} from "lit/decorators/custom-element.js";
import {property} from "lit/decorators/property.js"; import {property} from "lit/decorators/property.js";
@ -150,6 +150,10 @@ export class Et2Number extends Et2Textbox
// Add spinners // Add spinners
render(this._incrementButtonTemplate(), this); render(this._incrementButtonTemplate(), this);
if(this.value)
{
this.value = formatNumber(this.value, this.decimalSeparator, this.thousandsSeparator, this.precision);
}
} }
firstUpdated() 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) transformAttributes(attrs)
{ {
if(attrs.precision === 0 && typeof attrs.step === 'undefined') if(attrs.precision === 0 && typeof attrs.step === 'undefined')
@ -237,7 +249,6 @@ export class Et2Number extends Et2Textbox
val = this.min; val = this.min;
} }
super.value = formatNumber(val, this.decimalSeparator, this.thousandsSeparator, this.precision); super.value = formatNumber(val, this.decimalSeparator, this.thousandsSeparator, this.precision);
this.updateMaskValue();
} }
get value() : string get value() : string
@ -245,6 +256,13 @@ export class Et2Number extends Et2Textbox
return super.value; return super.value;
} }
protected updateMaskValue()
{}
/**
* Value returned to server is always no thousands separator, "." decimal separator
* @returns {any}
*/
getValue() : any getValue() : any
{ {
if(this.value == "" || typeof this.value == "undefined") if(this.value == "" || typeof this.value == "undefined")
@ -257,8 +275,7 @@ export class Et2Number extends Et2Textbox
get valueAsNumber() : number get valueAsNumber() : number
{ {
this.updateMaskValue(); let formattedValue : string | number = "" + this.stripFormat(this.value);
let formattedValue = (this._mask?.value ? this.stripFormat(this._mask.value) : this._mask?.unmaskedValue) ?? this.value;
if(formattedValue == "") if(formattedValue == "")
{ {
return 0; return 0;
@ -345,21 +362,6 @@ export class Et2Number extends Et2Textbox
return options; 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) private handleScroll(e)
@ -409,7 +411,7 @@ export class Et2Number extends Et2Textbox
* @param {number} value * @param {number} value
* @returns {string} * @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 // Split by . because value is a number, so . is decimal separator
let parts = ("" + value).split("."); let parts = ("" + value).split(".");

View File

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

View File

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