Skip to content

Commit

Permalink
Merge pull request #49 from krzysztof-zych/feature/negative-value
Browse files Browse the repository at this point in the history
Support for negative values
  • Loading branch information
changhuixu authored Jun 21, 2021
2 parents 50753eb + c82d876 commit a3a2f35
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 12 deletions.
26 changes: 25 additions & 1 deletion cypress/integration/clipboard-events.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', {
Expand Down Expand Up @@ -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('#negative-digit-only').clear();

cy.get('#negative-digit-only').then(($el) => {
$el[0].dispatchEvent(pasteEvent);
cy.get('#negative-digit-only').should('have.value', '-123');
});

cy.get('#negative-digit-only').then(($el) => {
$el[0].dispatchEvent(pasteEvent);
cy.get('#negative-digit-only').should('have.value', '-123123');
});

cy.get('#negative-digit-only').clear();
});
});
45 changes: 34 additions & 11 deletions projects/uiowa/digit-only/src/lib/digit-only.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
})
export class DigitOnlyDirective implements OnChanges {
private hasDecimalPoint = false;
private hasNegativeSign = false;
private navigationKeys = [
'Backspace',
'Delete',
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -145,6 +160,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) {
Expand Down Expand Up @@ -174,6 +194,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
Expand Down Expand Up @@ -206,22 +227,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;
Expand All @@ -247,11 +273,8 @@ export class DigitOnlyDirective implements OnChanges {
const selectionStart = this.inputElement.selectionStart ?? 0;
const selectionEnd = this.inputElement.selectionEnd ?? 0;
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);
}
}
3 changes: 3 additions & 0 deletions src/app/digit-only-demos/digit-only-demos.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ <h3><code>digitOnly</code> directive</h3>
placeholder="000"
maxlength="3"
/>

<label for="negative-digit-only">Digit Only input box that can be negative</label>
<input id="negative-digit-only" type="text" digitOnly [allowNegatives]="true" placeholder="-123"/>
</section>

<section>
Expand Down

0 comments on commit a3a2f35

Please sign in to comment.