From 959a4f525d8a9ef2311f17ae5fa83b8b819b86d6 Mon Sep 17 00:00:00 2001 From: Changhui Xu Date: Tue, 3 Aug 2021 17:32:20 -0500 Subject: [PATCH] release v2.3.0 -- adding support for negative values Angular v10/v11 version --- README.md | 2 + projects/uiowa/digit-only/README.md | 2 + projects/uiowa/digit-only/package.json | 2 +- .../src/lib/digit-only.directive.ts | 45 ++++++++++++++----- .../digit-only-demos.component.html | 3 ++ 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a83be56..2ea5c29 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ ## CHANGELOG +- **v2.3.0**: `digitOnly` directive now supports negative values (merges a pull request [#49](/../../pull/49)). + - **v2.2.3**: fix an issue ([#50](/../../issues/50)) in the `mask` directive: support dynamic pattern attribute binding. - **v2.2.2**: fix an issue ([#28](/../../issues/28)) to prevent [dead keys](https://en.wikipedia.org/wiki/Dead_key) in the `digitOnly` directive. diff --git a/projects/uiowa/digit-only/README.md b/projects/uiowa/digit-only/README.md index a83be56..2ea5c29 100644 --- a/projects/uiowa/digit-only/README.md +++ b/projects/uiowa/digit-only/README.md @@ -17,6 +17,8 @@ ## CHANGELOG +- **v2.3.0**: `digitOnly` directive now supports negative values (merges a pull request [#49](/../../pull/49)). + - **v2.2.3**: fix an issue ([#50](/../../issues/50)) in the `mask` directive: support dynamic pattern attribute binding. - **v2.2.2**: fix an issue ([#28](/../../issues/28)) to prevent [dead keys](https://en.wikipedia.org/wiki/Dead_key) in the `digitOnly` directive. diff --git a/projects/uiowa/digit-only/package.json b/projects/uiowa/digit-only/package.json index b634caa..890f1a6 100644 --- a/projects/uiowa/digit-only/package.json +++ b/projects/uiowa/digit-only/package.json @@ -1,6 +1,6 @@ { "name": "@uiowa/digit-only", - "version": "2.2.3", + "version": "2.3.0", "author": "Changhui Xu ", "description": "This package includes two Angular directives. The digitOnly directive only allows numbers in the input box when typing, pasting or drag/dropping. The mask directive checks the input pattern attribute.", "keywords": [ diff --git a/projects/uiowa/digit-only/src/lib/digit-only.directive.ts b/projects/uiowa/digit-only/src/lib/digit-only.directive.ts index fd0c309..9602547 100644 --- a/projects/uiowa/digit-only/src/lib/digit-only.directive.ts +++ b/projects/uiowa/digit-only/src/lib/digit-only.directive.ts @@ -12,6 +12,7 @@ import { }) export class DigitOnlyDirective implements OnChanges { private hasDecimalPoint = false; + private hasNegativeSign = false; private navigationKeys = [ 'Backspace', 'Delete', @@ -29,6 +30,8 @@ export class DigitOnlyDirective implements OnChanges { @Input() decimal = false; @Input() decimalSeparator = '.'; + @Input() allowNegatives= false; + @Input() negativeSign = '-'; @Input() min = -Infinity; @Input() max = Infinity; @Input() pattern?: string | RegExp; @@ -58,7 +61,8 @@ export class DigitOnlyDirective implements OnChanges { @HostListener('beforeinput', ['$event']) onBeforeInput(e: InputEvent): any { if (isNaN(Number(e.data))) { - if(e.data === this.decimalSeparator) { + if (e.data === this.decimalSeparator + || (e.data === this.negativeSign && this.allowNegatives)) { return; // go on } e.preventDefault(); @@ -97,6 +101,17 @@ export class DigitOnlyDirective implements OnChanges { } } + if (e.key === this.negativeSign && this.allowNegatives) { + newValue = this.forecastValue(e.key); + if (newValue.charAt(0) !== this.negativeSign || newValue.split(this.negativeSign).length > 2) { + e.preventDefault(); + return; + } else { + this.hasNegativeSign = newValue.split(this.negativeSign).length > -1; + return; + } + } + // Ensure that it is a number and stop the keypress if (e.key === ' ' || isNaN(Number(e.key))) { e.preventDefault(); @@ -143,6 +158,11 @@ export class DigitOnlyDirective implements OnChanges { private pasteData(pastedContent: string): void { const sanitizedContent = this.sanitizeInput(pastedContent); + if (sanitizedContent.includes(this.negativeSign) + && this.hasNegativeSign + && !this.getSelection().includes(this.negativeSign)) { + return; + } const pasted = document.execCommand('insertText', false, sanitizedContent); if (!pasted) { if (this.inputElement.setRangeText) { @@ -162,6 +182,7 @@ export class DigitOnlyDirective implements OnChanges { this.hasDecimalPoint = this.inputElement.value.indexOf(this.decimalSeparator) > -1; } + this.hasNegativeSign = this.inputElement.value.indexOf(this.negativeSign) > -1; } // The following 2 methods were added from the below article for browsers that do not support setRangeText @@ -194,22 +215,27 @@ export class DigitOnlyDirective implements OnChanges { private sanitizeInput(input: string): string { let result = ''; + let regex; if (this.decimal && this.isValidDecimal(input)) { - const regex = new RegExp(`[^0-9${this.decimalSeparator}]`, 'g'); - result = input.replace(regex, ''); + regex = new RegExp(`${this.getNegativeSignRegExp()}[^0-9${this.decimalSeparator}]`, 'g'); } else { - result = input.replace(/[^0-9]/g, ''); + regex = new RegExp(`${this.getNegativeSignRegExp()}[^0-9]`, 'g'); } + result = input.replace(regex, ''); const maxLength = this.inputElement.maxLength; if (maxLength > 0) { // the input element has maxLength limit - const allowedLength = maxLength - this.inputElement.value.length; + const allowedLength = maxLength - this.inputElement.value.length + (result.includes(`${this.negativeSign}`) ? 1 : 0); result = allowedLength > 0 ? result.substring(0, allowedLength) : ''; } return result; } + private getNegativeSignRegExp() : string { + return this.allowNegatives && (!this.hasNegativeSign || this.getSelection().includes(this.negativeSign)) ? `(?!^${this.negativeSign})` : ''; + } + private isValidDecimal(string: string): boolean { if (!this.hasDecimalPoint) { return string.split(this.decimalSeparator).length <= 2; @@ -235,11 +261,8 @@ export class DigitOnlyDirective implements OnChanges { const selectionStart = this.inputElement.selectionStart; const selectionEnd = this.inputElement.selectionEnd; const oldValue = this.inputElement.value; - const selection = oldValue.substring(selectionStart, selectionEnd); - return selection - ? oldValue.replace(selection, key) - : oldValue.substring(0, selectionStart) + - key + - oldValue.substring(selectionStart); + return oldValue.substring(0, selectionStart) + + key + + oldValue.substring(selectionEnd); } } diff --git a/src/app/digit-only-demos/digit-only-demos.component.html b/src/app/digit-only-demos/digit-only-demos.component.html index b89685b..c653be3 100644 --- a/src/app/digit-only-demos/digit-only-demos.component.html +++ b/src/app/digit-only-demos/digit-only-demos.component.html @@ -16,6 +16,9 @@

digitOnly directive

placeholder="000" maxlength="3" /> + + +