How to restrict special characters in the input field using Angular 2 / Typescript
Asked Answered
P

7

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));
}
Pentothal answered 13/7, 2017 at 5:50 Comment(1)
you can use ng-pattern for it. it is very simple and usefulUrsola
S
34

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.

Sentimental answered 13/7, 2017 at 11:51 Comment(5)
Your solution is fine but not working for copy and paste .. Thankful to you if u give solution for thatBloodshot
@Bloodshot It was coded to solve the problem of questioner so might need to be altered by your need.Sentimental
@MaulikModi yes right .. but I problem is solved I fixed it by myself :)Bloodshot
One problem with this approach will be when user will paste data it wont work. You should call function on blur too.Glimmer
I'm working with ionic angular. Can you help me to achieve same functionality with android?Perpetuity
L
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.

Lignite answered 24/11, 2017 at 13:35 Comment(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. ThanksPapaverine
P
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)"/>
Putrid answered 13/7, 2017 at 6:1 Comment(9)
Thanks for the replying. I will try and tell youPentothal
sorry it is not working with me. Il paste what i tried with my code. I had updated my code please have a lookPentothal
e is the event. you can run above code it should work. based on that modify it in your typescriptPutrid
Ya the above snippet is working the same way i wanted. I am trying but not gettingPentothal
i can show demo in angular 1 but you want angular 2 alone?Putrid
ya i need in angular2 onlyPentothal
try this... updated my answer. try with patterns. hope it should work for youPutrid
ya will try and tellPentothal
No sorry, it is not takingPentothal
W
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>
Woolley answered 24/3, 2020 at 11:31 Comment(0)
A
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) {
    }
}
Annual answered 1/4, 2020 at 9:50 Comment(0)
A
-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

Aberdeen answered 13/7, 2017 at 6:27 Comment(4)
Thanks for replying i will tryPentothal
$scope is not present in angular2Pentothal
you can use 'this' insteadAberdeen
I got this error :There is no directive with "exportAs" set to "ngModel" ("ype="text" (ngModelChange)="myValidationFunction()" mdInput name="name" placeholder="Company Name" [ERROR ->]#name="ngModel" ng-model="name" minlength="3" required>Pentothal
H
-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>
Hibben answered 13/7, 2017 at 7:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.