19

I am new to Angular 2. I need to prevent special characters from being typed in the input field. If I type alphanumerics, it must accept them, while special characters should be blocked. Can anyone help please.

I am sharing the code here.

In HTML:

<md-input-container>
   <input type="text" (ngModelChange)="omit_special_char($event)" mdInput name="name" [(ngModel)]="company.name" placeholder="Company Name" #name="ngModel" minlength="3" required>
</md-input-container>

In TS:

public e: any;

omit_special_char(val)
{
   var k;
   document.all ? k = this.e.keyCode : k = this.e.which;
   return ((k > 64 && k < 91) || (k > 96 && k < 123) || k == 8 || k == 32 || (k >= 48 && k <= 57));
}
MathMax
  • 571
  • 7
  • 22
Bhrungarajni
  • 2,415
  • 11
  • 44
  • 88

7 Answers7

32

You were doing everything right. Just the function needs to be changed a bit. You were using ngModelChange to bind event which is not there. You can use keypress event handler as shown below.

HTML

   <md-input-container>
    <input type="text" (keypress)="omit_special_char($event)" mdInput name="name" [(ngModel)]="company.name" placeholder="Company Name" #name="ngModel" minlength="3" required>
    </md-input-container>

Component

omit_special_char(event)
{   
   var k;  
   k = event.charCode;  //         k = event.keyCode;  (Both can be used)
   return((k > 64 && k < 91) || (k > 96 && k < 123) || k == 8 || k == 32 || (k >= 48 && k <= 57)); 
}

"event" is the object of "$event" itself which you have passed earlier. Try this one, it will surely work with angular2.

Maulik Modi
  • 1,205
  • 12
  • 22
27

I combined several answers from this and other posts and created my custom directive for handling both manual input and pasting data.

The directive:

import { Directive, ElementRef, HostListener, Input } from '@angular/core';
    @Directive({
        selector: '[appInputRestriction]'
    })
    export class InputRestrictionDirective {
        inputElement: ElementRef;

        @Input('appInputRestriction') appInputRestriction: string;
        arabicRegex = '[\u0600-\u06FF]';

        constructor(el: ElementRef) {
            this.inputElement = el;
        }

        @HostListener('keypress', ['$event']) onKeyPress(event) {
            if (this.appInputRestriction === 'integer') {
                this.integerOnly(event);
            } else if (this.appInputRestriction === 'noSpecialChars') {
                this.noSpecialChars(event);
            }
        }

        integerOnly(event) {
            const e = <KeyboardEvent>event;
            if (e.key === 'Tab' || e.key === 'TAB') {
                return;
            }
            if ([46, 8, 9, 27, 13, 110].indexOf(e.keyCode) !== -1 ||
                // Allow: Ctrl+A
                (e.keyCode === 65 && e.ctrlKey === true) ||
                // Allow: Ctrl+C
                (e.keyCode === 67 && e.ctrlKey === true) ||
                // Allow: Ctrl+V
                (e.keyCode === 86 && e.ctrlKey === true) ||
                // Allow: Ctrl+X
                (e.keyCode === 88 && e.ctrlKey === true)) {
                // let it happen, don't do anything
                return;
            }
            if (['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'].indexOf(e.key) === -1) {
                e.preventDefault();
            }
        }

        noSpecialChars(event) {
            const e = <KeyboardEvent>event;
            if (e.key === 'Tab' || e.key === 'TAB') {
                return;
            }
            let k;
            k = event.keyCode;  // k = event.charCode;  (Both can be used)
            if ((k > 64 && k < 91) || (k > 96 && k < 123) || k === 8 || k === 32 || (k >= 48 && k <= 57)) {
                return;
            }
            const ch = String.fromCharCode(e.keyCode);
            const regEx = new RegExp(this.arabicRegex);
            if (regEx.test(ch)) {
                return;
            }
            e.preventDefault();
        }

        @HostListener('paste', ['$event']) onPaste(event) {
            let regex;
            if (this.appInputRestriction === 'integer') {
                regex = /[0-9]/g;
            } else if (this.appInputRestriction === 'noSpecialChars') {
                regex = /[a-zA-Z0-9\u0600-\u06FF]/g;
            }
            const e = <ClipboardEvent>event;
            const pasteData = e.clipboardData.getData('text/plain');
            let m;
            let matches = 0;
            while ((m = regex.exec(pasteData)) !== null) {
                // This is necessary to avoid infinite loops with zero-width matches
                if (m.index === regex.lastIndex) {
                    regex.lastIndex++;
                }
                // The result can be accessed through the `m`-variable.
                m.forEach((match, groupIndex) => {
                    matches++;
                });
            }
            if (matches === pasteData.length) {
                return;
            } else {
                e.preventDefault();
            }
        }

    }

Usage:

<input type="text" appInputRestriction="noSpecialChars" class="form-control-full" [(ngModel)]="noSpecialCharsModel" [ngModelOptions]="{standalone: true}" [disabled]="isSelected" required>

<input type="text" appInputRestriction="integer" class="form-control-full" [(ngModel)]="integerModel" [ngModelOptions]="{standalone: true}">

This is actually my first stackoverflow answer so I hope it helps.

sivi911
  • 311
  • 3
  • 5
  • 1
    thanks I used your code, however I changed it a bit since your code was blocking any paste data if it was invalid (containing special chars). However on my side I wanted to remove the special chars, so I replaced a slight portion of your code and it works great. Thanks – ghiscoding Feb 28 '19 at 18:08
3

angular2 code sample.

<input type="text" pattern="/[A-Z]{5}\d{4}[A-Z]{1}/i">

or

<md-input-container>
<input type="text" (keypress)="omit_special_char($event)" mdInput name="name" [(ngModel)]="company.name" placeholder="Company Name" #name="ngModel" minlength="3" required>
</md-input-container>

omit_special_char(val)
{
   var k;
    document.all ? k = this.e.keyCode : k = this.e.which;
    return ((k > 64 && k < 91) || (k > 96 && k < 123) || k == 8 || k == 32 || (k >= 48 && k <= 57));
}

here is the working sample in pure javascript because angular2/typescript wont support in StackOverflow.

function omit_special_char(e) {
    var k;
    document.all ? k = e.keyCode : k = e.which;
    return ((k > 64 && k < 91) || (k > 96 && k < 123) || k == 8 || k == 32 || (k >= 48 && k <= 57));
}
<input type="text" onkeypress="return omit_special_char(event)"/>
Mohideen bin Mohammed
  • 18,813
  • 10
  • 112
  • 118
3

You can use pattern in input tag Works fine with angular7.

for validating special characters

                <input #Name="ngModel" type="text" name="Name" required maxlength="256" minlength="2"
                    [(ngModel)]="Name" class="validate form-control" pattern="^[a-zA-Z0-9]+$">
                </div>

allowing Space use => pattern="^[a-zA-Z0-9 ]+$">

full usage with showing Validation Message :

                <label for="Name" class="form-label">{{"Name" | localize}}*</label>

                <div class="input-group"><input #dashboardName="ngModel" type="text" name="Name" required maxlength="256" minlength="2"
                    [(ngModel)]="Name" class="validate form-control" pattern="^[a-zA-Z0-9 ]+$">
                </div>
                <validation-messages [formCtrl]="Name"></validation-messages>
            </div>
Manu A.T
  • 31
  • 4
0

You could also made used of Regex pattern

<md-input-container>
<input type="text" (ngModelChange)="omit_special_char($event)" mdInput name="name" [(ngModel)]="company.name" placeholder="Company Name" #name="ngModel" minlength="3" required>
</md-input-container>

public omit_special_char(e: any) {
    try {
        let k;
        if (/^[a-zA-Z0-9\s]*$/.test(e.key)) {
            return true;
        } else {
            e.preventDefault();
            return false;
        }
    } catch (e) {
    }
}
Nɪsʜᴀɴᴛʜ ॐ
  • 2,756
  • 4
  • 33
  • 57
-1

you can go with ng-change attribute then call function in javascript and validate there..

<md-input-container> 
<input type="text" mdInput ng-change="myValidationFunction()" name="name" placeholder="Company Name" #name="ngModel" ng-model="name" minlength="3" required>
</md-input-container>

In javaScript:

myValidateFunction() 
{
  if ($scope.name.matches("^[a-zA-Z0-9]+$")) {
     return true;
  } 
  else {
     return false
  }
}

Based on function result you can do what you want ...validate or disallow or if you want to show any CSS msg then you can

Sami
  • 21
  • 4
-2

You can use html5 pattern validator as

<input type="text" (ngModelChange)="omit_special_char($event)" mdInput name="name" [(ngModel)]="company.name" placeholder="Company Name" #name="ngModel" minlength="3" required pattern="[a-zA-Z0-9]">

Add novalidate to form and then you can display error for same as

<div *ngIf="name?.errors.pattern && name.dirty && name.invalid">Error Message</div>
Prathmesh Dali
  • 2,250
  • 1
  • 18
  • 21