2

Angular 2 form Validation

scenario:

If user try to enter the special character in to the input type="text", it should be prevented from being entered ?

special characters should not appear in to the corresponding text box ?

mani R
  • 361
  • 4
  • 16
  • Please refer this - http://stackoverflow.com/questions/34559212/how-to-add-form-validation-pattern-in-angular2 – Sanket Jun 21 '16 at 06:33
  • @Sanket, validation pattern changes dynamically, but my behaviour of input control should not allow the user to enter the pattern mentioned for that control – mani R Jun 21 '16 at 06:46
  • 1
    This approach might work for you http://stackoverflow.com/questions/37800841/input-mask-fields-in-angular2-forms – Günter Zöchbauer Jun 21 '16 at 07:06
  • @GünterZöchbauer the above approach works good. Now i face problem with caret position with the validation mask. when i type some string to the input [type ="text"]. with that validation mask directive i try to replace the input string with matched pattern. scenario: when i try to edit from middle of the string ( placing the caret position between the string ) entered in input [type ="text"], the caret position shift to last. it doesn't allow to change in middle of the string. – mani R Aug 30 '16 at 07:20
  • Sorry, don't know about that. Maybe someone else. A Plunker to reproduce might help as well. – Günter Zöchbauer Aug 30 '16 at 07:41

4 Answers4

0

code, which shown below fix the caret position problem
1. changing the event type to '(input)' inside the host listener.
2. inside the class define the start and end position of the caret, it solves the problem

@Directive({
selector: '[ngModel][maskSpecialCharacter]',
host: {
    '(ngModelChange)': 'onInputChange($event)',
    '(input)': 'onInputChange($event.target.value, true)'
 }
})
      export class SpecialCharacterMask {
         constructor(public model: NgControl, public ele: ElementRef, public render: Renderer) { }

onInputChange(event, backspace) {
    var position = this.ele.nativeElement.selectionStart;
    var value = event.replace(/[!$%^&*()+|~=`{}\[\]:";#@'<>?,.\/\\]/gi, '');
    this.render.setElementProperty(this.ele.nativeElement, "value", value);
    this.ele.nativeElement.selectionEnd = position;
}
}
mani R
  • 361
  • 4
  • 16
0

You can create a custom validator,

import { FormControl } from '@angular/forms'

export function restrictedWords(words) {
    return (control: FormControl): { [key: string]: any } => {
        if (!words) return null
        var invalidWords = words.map(w => control.value.includes(w) ? w : null)
            .filter(w => w != null)
        return invalidWords && invalidWords.length > 0
            ? { 'restrictedWords': invalidWords.join(', ') }
            : null
    }
}

Call the custom validator function from your form,

this.textBox1 = new FormControl('',[Validators.required, Validators.maxLength(400), restrictedWords(['foo','bar'])])
Bharathkumar V
  • 327
  • 5
  • 13
0

Approach for Angular Reactive Form:

Need to add a Validator in form Validation. Also, below regex will not work with internationalization. Please change the regex as per need.

    this.form= this.formBuilder.group({
        name: ['', [ Validators.required, Validators.pattern(/^[a-zA-Z0-9!@#$%^&*()]+$/)] ],
        description: ['']
    });

Please note you don't need quotes for Validators.pattern method

Approach 2

export function isSecuredInput(input: string): boolean {
    const tagBody = '(?:[^"\'>]|"[^"]*"|\'[^\']*\')*';
    const tagOrComment = new RegExp(
        '<(?:'
        // Comment body.
        + '!--(?:(?:-*[^->])*--+|-?)'
        // Special "raw text" elements whose content should be elided.
        + '|script\\b' + tagBody + '>[\\s\\S]*?</script\\s*'
        + '|style\\b' + tagBody + '>[\\s\\S]*?</style\\s*'
        // Regular name
        + '|/?[a-z]'
        + tagBody
        + ')>',
        'gi');

    return input.search(tagOrComment) === -1 ? true : false;
}

Changes in Form:

isValidInput(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: any } => {
        if (!isNullOrUndefined(control.value)) {
            return isSecuredInput(control.value.toString()) ? null : { invalid: true};
        }
        return null;
    };
}

and Form would be

this.form = this.formBuilder.group({
        name:  new FormControl('', {
            validators: [Validators.required, this.isValidInput()],
            updateOn: 'change'
        })
})

Source isSecure is from Sanitize/Rewrite HTML on the Client Side

Chetan Laddha
  • 993
  • 8
  • 22
0

Try Using Pattern as

 this.form= this.fb.group({
        name: ['', [Validators.pattern('[a-zA-Z0-9 ]')]],
 });
Mustafa Kunwa
  • 821
  • 1
  • 9
  • 19