Abhilash Gudapati
Abhilash Gudapati

Reputation: 41

ngx-mask to accept negative numbers

We are using MaskDirective & MaskService from ngx-mask in order to make users accept input currency in the following format: 000000.00.

The following is my directive. I'm using input type="decimal". Now I have a scenario wherein one situation this directive should accept a negative number (if there is one).

How can I implement this? Tried using "specialCharacters" but I couldn't get through.

Any help is highly appreciated. Thanks in advance.

`@Directive({
  selector: 'input[type=decimal]',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DecimalDirective),
      multi: true,
    },
    MaskService,
  ],
})
export class DecimalDirective extends MaskDirective implements OnInit {
  @HostBinding('type') public type = 'text';

  ngOnInit() {
    this.maskExpression = '099999.00';
    this.dropSpecialCharacters = false;
  }
}`

Usage:

`<input type="decimal" name="sampleAmount" formControlName="sampleAmount" class="form-control" placeholder="0.00">`

Upvotes: 3

Views: 5529

Answers (3)

Bence Szab&#243;
Bence Szab&#243;

Reputation: 143

In newer ngx-mask versions there is an input option for this called allowNegativeNumbers. You should try the following:

ngOnInit() {
    this.maskExpression = '099999.00';
    this.allowNegativeNumbers = true; // <----
}

Upvotes: 1

Ryan
Ryan

Reputation: 33

Based on @AnisNoorAlis answer and https://github.com/JsDaddy/ngx-mask/issues/175.

(Using https://www.npmjs.com/package/ngx-mask 12.0.0)

I tried to complete this using mask and patterns but still failed due to what I think it a bug in the ngx-mask code.

Attempts:

  1. The regex optional '?' is moved to the mask otherwise any character could be entered as the first character.
  2. And additional 0 otherwise it doesn't work. See more detail below.
  3. Using '9' instead of 'V' or any letter (only because formatter removes ' for characters and then it didn't like it...
mask(){
    float ? "9?00*.00" : "9?00*";
}

customPatterns = {
    '9': {pattern: new RegExp('-')},
    '0': {pattern: new RegExp('[0-9]')}
}

<input [mask]=mask() [patterns]="customPatterns" [dropSpecialCharacters]="false">

But this does not allow the entry of single digit decimals i.e. 9.3, 1.12. So nearly but still is not acceptable.

After delving into the ngx-mask code:

There is either missing documentation or a bug that requires the optional character '?' in the mask to be follow by what it can be if it's not that. I think the cursor below should be += 2. But adding an additional 0 in the mask works. The offending code is in applyMask.

else if (maskExpression[cursor + 1] === '?' &&
         this._checkSymbolMask(inputSymbol, maskExpression[cursor + 2])) {
    result += inputSymbol;
    cursor += 3;
}

Also allowNegativeNumbers only works if the mask starts with 'percent' or 'separator'.

I wanted to understand what was going on but there is an alternative solution: use the 'separator' mask and set separator to ''. There is no way to limit the digits before the decimal using this method; 'separatorLimit' implies it's possible but it does not do this. I don't really understand the docs for it.

mask(){
    float ? "separator.4" : "separator.0";
}

<input [mask]="mask()" [thousandSeparator]="''">

Upvotes: 1

AnisNoorAli
AnisNoorAli

Reputation: 81

<input mask="V0*.00" 
      [patterns]="customPatterns" 
      [dropSpecialCharacters]="false">

customPatterns = {
    'V': {pattern: new RegExp('-?')},
    '0': {pattern: new RegExp('[0-9]')}
  }

Reference

Upvotes: 2

Related Questions