0

I have a requirement that certain input fields need to be masked. Example, desired amount should be displayed as $44,444. I can achieve the input masking by using text-mask (https://github.com/text-mask/text-mask). The problem I am encountering is that the masking breaks my reactive form validators.

component:

import {WithinLoanRangeDirective} from './within-loan-range.directive'

this.applicationForm = this.fb.group({
  desiredAmount: ['', [Validators.required, WithinLoanRangeDirective] ]
})

template:

<input
 [textMask]="{mask: numberMask}"
 mdInput
 formControlName="desiredLoanAmount   
 type="tel"            
 > <!--type tel to pop numpad-->

<div> {{ applicationForm.controls['desiredLoanAmount'].hasError('withinLoanAmountRange')}}</div>

The validators are now checking min and max against the masked input ($44,444) instead of (44444). Is there a way to format the value before setting it in model?

1 Answer 1

1

You need to create a custom validator (Directive) and strip out all non-numeric characters and set a min max as arguments (or hard code them in the directive..), then return the validity.

https://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html

import { Directive } from '@angular/core';
import { NG_VALIDATORS, Validator, FormControl } from '@angular/forms';

@Directive({
    selector: '[ngModel][withinLoanAmountRange], [formControl][withinLoanAmountRange]',
    providers: [
        {
            provide: NG_VALIDATORS,
            useClass: WithinLoanRangeDirective,
            multi: true,
        }
    ]
})
export class WithinLoanRangeDirective implements Validator {
    constructor() { 
    }
    validate(c: FormControl) {
        let loanValue = c.value.replace(/\D/g,''); 

        return (loanValue >= 1000 && loanValue <= 20000) ? null : {
            withinLoanAmountRange: { message: 'Loan Needs to be between 1 and $5k' }
        };
    }
}




<input
 [textMask]="{mask: numberMask}"
 withinLoanAmountRange
 mdInput
 formControlName="desiredLoanAmount              
 >
Sign up to request clarification or add additional context in comments.

6 Comments

How do I get that withinLoanAmountRange.message back in the template? Think I am missing something to get this wired up. I put a console.log(loanValue) after "let loanValue" and nothing gets printed to console when typing.
applicationForm .controls['desiredLoanAmount '].hasError('withinLoanAmountRange')) in the template
Alternatively, you can import the directive into the component and add it into the validators array, instead of in the template.
import { WithinLoanRangeDirective} from '../....directive'; desiredAmount: ['', [Validators.required, WithinLoanRangeDirective] ]
Updated original question with my implementation. My directive is exactly as you posted above. The error returned to template is always false.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.