From 42758909b80009cb097c732195383e8374067d7e Mon Sep 17 00:00:00 2001 From: Krzysztof Zych Date: Thu, 1 Apr 2021 09:22:58 +0200 Subject: [PATCH 1/3] #34 support for a negative values --- cypress/integration/clipboard-events.spec.ts | 26 +++++++++++++++- .../src/lib/digit-only.directive.ts | 30 +++++++++++++++---- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/cypress/integration/clipboard-events.spec.ts b/cypress/integration/clipboard-events.spec.ts index dbba8d5..1d651fd 100644 --- a/cypress/integration/clipboard-events.spec.ts +++ b/cypress/integration/clipboard-events.spec.ts @@ -135,7 +135,7 @@ describe('Copy & Paste', () => { cy.get('#digit-only-decimal').clear(); }); - it.only('s', ()=> { + it('s', ()=> { const dt = new DataTransfer(); dt.setData('text/plain', 'abc1.0s.1'); const pasteEvent = new ClipboardEvent('paste', { @@ -264,4 +264,28 @@ describe('Copy & Paste', () => { cy.get('#decimal-number').clear(); }); + + it('should accept negative sign (only once)', () => { + const dt = new DataTransfer(); + dt.setData('text/plain', '-123'); + const pasteEvent = new ClipboardEvent('paste', { + clipboardData: dt, + bubbles: true, + cancelable: true, + }); + + cy.get('#digit-only').clear(); + + cy.get('#digit-only').then(($el) => { + $el[0].dispatchEvent(pasteEvent); + cy.get('#digit-only').should('have.value', '-123'); + }); + + cy.get('#digit-only').then(($el) => { + $el[0].dispatchEvent(pasteEvent); + cy.get('#digit-only').should('have.value', '-123123'); + }); + + cy.get('#digit-only').clear(); + }); }); 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..3d5a6f0 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,7 @@ export class DigitOnlyDirective implements OnChanges { @Input() decimal = false; @Input() decimalSeparator = '.'; + @Input() negativeSign = '-'; @Input() min = -Infinity; @Input() max = Infinity; @Input() pattern?: string | RegExp; @@ -58,7 +60,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) { return; // go on } e.preventDefault(); @@ -97,6 +100,17 @@ export class DigitOnlyDirective implements OnChanges { } } + if (e.key === this.negativeSign && this.min < 0) { + 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(); @@ -162,6 +176,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 +209,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.hasNegativeSign ? `(?!^${this.negativeSign})` : ''; + } + private isValidDecimal(string: string): boolean { if (!this.hasDecimalPoint) { return string.split(this.decimalSeparator).length <= 2; From 2cd08c8d9b1eb90c356e05d122d01b897962e97d Mon Sep 17 00:00:00 2001 From: Krzysztof Zych Date: Sun, 11 Apr 2021 22:03:20 +0200 Subject: [PATCH 2/3] #34 support for a negative values - post review fixes --- .../digit-only/src/lib/digit-only.directive.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) 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 3d5a6f0..dfc009e 100644 --- a/projects/uiowa/digit-only/src/lib/digit-only.directive.ts +++ b/projects/uiowa/digit-only/src/lib/digit-only.directive.ts @@ -157,6 +157,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) { @@ -227,7 +232,7 @@ export class DigitOnlyDirective implements OnChanges { } private getNegativeSignRegExp() : string { - return !this.hasNegativeSign ? `(?!^${this.negativeSign})` : ''; + return !this.hasNegativeSign || this.getSelection().includes(this.negativeSign) ? `(?!^${this.negativeSign})` : ''; } private isValidDecimal(string: string): boolean { @@ -255,11 +260,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); } } From c82d876bf5c908ab3159b272436e35700d2976e7 Mon Sep 17 00:00:00 2001 From: Krzysztof Zych Date: Mon, 21 Jun 2021 12:34:35 +0200 Subject: [PATCH 3/3] #34 support for a negative values - make sure that new feature will not break existing applications --- cypress/integration/clipboard-events.spec.ts | 12 ++++++------ .../uiowa/digit-only/src/lib/digit-only.directive.ts | 7 ++++--- .../digit-only-demos/digit-only-demos.component.html | 3 +++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cypress/integration/clipboard-events.spec.ts b/cypress/integration/clipboard-events.spec.ts index 1d651fd..745db78 100644 --- a/cypress/integration/clipboard-events.spec.ts +++ b/cypress/integration/clipboard-events.spec.ts @@ -274,18 +274,18 @@ describe('Copy & Paste', () => { cancelable: true, }); - cy.get('#digit-only').clear(); + cy.get('#negative-digit-only').clear(); - cy.get('#digit-only').then(($el) => { + cy.get('#negative-digit-only').then(($el) => { $el[0].dispatchEvent(pasteEvent); - cy.get('#digit-only').should('have.value', '-123'); + cy.get('#negative-digit-only').should('have.value', '-123'); }); - cy.get('#digit-only').then(($el) => { + cy.get('#negative-digit-only').then(($el) => { $el[0].dispatchEvent(pasteEvent); - cy.get('#digit-only').should('have.value', '-123123'); + cy.get('#negative-digit-only').should('have.value', '-123123'); }); - cy.get('#digit-only').clear(); + cy.get('#negative-digit-only').clear(); }); }); 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 241d0da..256ab65 100644 --- a/projects/uiowa/digit-only/src/lib/digit-only.directive.ts +++ b/projects/uiowa/digit-only/src/lib/digit-only.directive.ts @@ -30,6 +30,7 @@ export class DigitOnlyDirective implements OnChanges { @Input() decimal = false; @Input() decimalSeparator = '.'; + @Input() allowNegatives= false; @Input() negativeSign = '-'; @Input() min = -Infinity; @Input() max = Infinity; @@ -61,7 +62,7 @@ export class DigitOnlyDirective implements OnChanges { onBeforeInput(e: InputEvent): any { if (isNaN(Number(e.data))) { if (e.data === this.decimalSeparator - || e.data === this.negativeSign) { + || (e.data === this.negativeSign && this.allowNegatives)) { return; // go on } e.preventDefault(); @@ -100,7 +101,7 @@ export class DigitOnlyDirective implements OnChanges { } } - if (e.key === this.negativeSign && this.min < 0) { + 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(); @@ -244,7 +245,7 @@ export class DigitOnlyDirective implements OnChanges { } private getNegativeSignRegExp() : string { - return !this.hasNegativeSign || this.getSelection().includes(this.negativeSign) ? `(?!^${this.negativeSign})` : ''; + return this.allowNegatives && (!this.hasNegativeSign || this.getSelection().includes(this.negativeSign)) ? `(?!^${this.negativeSign})` : ''; } private isValidDecimal(string: string): boolean { 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 61df59f..7f21088 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" /> + + +