From 9df4c98106866391fb34fc833ed2b3bbb0ec37bd Mon Sep 17 00:00:00 2001 From: Alexey Raksha Date: Mon, 29 Jan 2024 18:51:35 +0300 Subject: [PATCH] fix #11442 numpad decimal separator should support all keyboard layout --- .../inputnumber/inputnumber.spec.ts | 38 ++++++++++++++++++- src/app/components/inputnumber/inputnumber.ts | 27 ++++++++----- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/app/components/inputnumber/inputnumber.spec.ts b/src/app/components/inputnumber/inputnumber.spec.ts index c8636c4b350..f0e105eebe4 100755 --- a/src/app/components/inputnumber/inputnumber.spec.ts +++ b/src/app/components/inputnumber/inputnumber.spec.ts @@ -6,11 +6,12 @@ import { Component } from '@angular/core'; import { By } from '@angular/platform-browser'; @Component({ - template: `` + template: `` }) class TestInputNumberComponent { val: number; readonly: boolean = true; + minFractionDigits = 2; } describe('InputNumber', () => { @@ -35,4 +36,39 @@ describe('InputNumber', () => { const inputMaskEl = fixture.debugElement.query(By.css('input')); expect(inputMaskEl.nativeElement).toBeTruthy(); }); + describe('Numepad decimal', () => { + const pressFiveEvent = new KeyboardEvent('event', { + code: 'Digit5', + key: '5', + keyCode: '5'.charCodeAt(0) + }); + const pressNumpadDecimalWithDotEvent = new KeyboardEvent('event', { + code: 'NumpadDecimal', + key: '.', + keyCode: '.'.charCodeAt(0) + }); + const pressNumpadDecimalWithCommaEvent = new KeyboardEvent('event', { + code: 'NumpadDecimal', + key: ',', + keyCode: ','.charCodeAt(0) + }); + + beforeEach(() => { + testComponent.readonly = false; + testComponent.val = 0; + fixture.detectChanges(); + }); + it('should accept numpad dot as decimal separator', () => { + inputNumber.onInputKeyPress(pressFiveEvent); + inputNumber.onInputKeyPress(pressNumpadDecimalWithDotEvent); + inputNumber.onInputKeyPress(pressFiveEvent); + expect(testComponent.val).toEqual(5.5); + }); + it('should accept numpad comma as decimal separator', () => { + inputNumber.onInputKeyPress(pressFiveEvent); + inputNumber.onInputKeyPress(pressNumpadDecimalWithCommaEvent); + inputNumber.onInputKeyPress(pressFiveEvent); + expect(testComponent.val).toEqual(5.5); + }); + }); }); diff --git a/src/app/components/inputnumber/inputnumber.ts b/src/app/components/inputnumber/inputnumber.ts index 5238e77fe08..25faf7546f3 100644 --- a/src/app/components/inputnumber/inputnumber.ts +++ b/src/app/components/inputnumber/inputnumber.ts @@ -482,6 +482,8 @@ export class InputNumber implements OnInit, AfterContentInit, OnChanges, Control _decimal: any; + _decimalChar: string; + _group: any; _minusSign: any; @@ -554,6 +556,7 @@ export class InputNumber implements OnInit, AfterContentInit, OnChanges, Control this._minusSign = this.getMinusSignExpression(); this._currency = this.getCurrencyExpression(); this._decimal = this.getDecimalExpression(); + this._decimalChar = this.getDecimalChar(); this._suffix = this.getSuffixExpression(); this._prefix = this.getPrefixExpression(); this._index = (d: any) => index.get(d); @@ -570,15 +573,16 @@ export class InputNumber implements OnInit, AfterContentInit, OnChanges, Control } getDecimalExpression(): RegExp { + const decimalChar = this.getDecimalChar(); + return new RegExp(`[${decimalChar}]`, 'g'); + } + getDecimalChar(): string { const formatter = new Intl.NumberFormat(this.locale, { ...this.getOptions(), useGrouping: false }); - return new RegExp( - `[${formatter - .format(1.1) - .replace(this._currency as RegExp | string, '') - .trim() - .replace(this._numeral, '')}]`, - 'g' - ); + return formatter + .format(1.1) + .replace(this._currency as RegExp | string, '') + .trim() + .replace(this._numeral, ''); } getGroupingExpression(): RegExp { @@ -953,12 +957,17 @@ export class InputNumber implements OnInit, AfterContentInit, OnChanges, Control let code = event.which || event.keyCode; let char = String.fromCharCode(code); - const isDecimalSign = this.isDecimalSign(char); + let isDecimalSign = this.isDecimalSign(char); const isMinusSign = this.isMinusSign(char); if (code != 13) { event.preventDefault(); } + if (!isDecimalSign && event.code === 'NumpadDecimal') { + isDecimalSign = true; + char = this._decimalChar; + code = char.charCodeAt(0); + } const newValue = this.parseValue(this.input.nativeElement.value + char); const newValueStr = newValue != null ? newValue.toString() : '';