0

I am adding validation to some input fields in my reactive class-driven form. Here is an example of some of my input fields:

.html

<input matInput formControlName="{{ field?.controlName }}" maxLength="{{ field?.maxLength }}" placeholder="{{ field?.label }}">
<span matSuffix class="input-suffix">Required</span>

In the browser

enter image description here

I would like to know how to add a feature that prevents any special characters from being entered.

NOTE: I am already using a custom validator function that will raise a small error message if any characters match a regex.

enter image description here

However, I want it to prevent resticted characters from even appearing. So if a user typed '%' or '&' nothing would happen. Also, I want to allow some characters, like apostrophes or hypens.

4 Answers4

1

A clean way since you are using angular material, is to do a custom form field. This would allow it to flow nicely and be used like the rest of your form fields.

There are other options if needed, like answered for this similiar question.

blapaz
  • 334
  • 2
  • 11
0

Try this.
Angular Controller:

document.getElementById("id").onkeypress = function(e) {
    var str = String.fromCharCode(e.which);
    if ("%&".indexOf(str) >= 0)
        return false;
};


HTML Input:

<input type='text' id='id' value='' onpaste="return false"/>

Let me know if that works for your situation.

gbeegs
  • 11
  • 5
0

If you want something versatile, reusable and flexible, you could write a directive for this that captures input events and filters as needed like:

 @Directive({
   selector: 'input[regexInput]',
   providers: [
     {
       provide: NG_VALUE_ACCESSOR,
       useExisting: RegexInputDirective,
       multi: true
     }
   ]
 })
 export class RegexInputDirective implements ControlValueAccessor {
   private _regex: RegExp;
   @Input()
   set regexInput(regex: string | RegExp) {
     this._regex = (typeof regex === 'string') ? new RegExp(regex, "g") : regex;
   }

   constructor(private elementRef: ElementRef<HTMLInputElement>) { }

   writeValue(val: any): void { }

   onChange = (value: any) => {};

   onTouched = () => {};

   registerOnChange(fn: (val: any) => void): void {
     this.onChange = fn;
   }
   registerOnTouched(fn: any): void {
     this.onTouched = fn;
   }

   @HostListener('input', ['$event'])
   onInput(event: Event) {
     if (!this._regex) {
       throw new Error('RegExp required for regexInput');
     }
     let val = (<HTMLInputElement>event.target).value;
     let cleanVal = (val.match(this._regex) || []).join("");
     this.elementRef.nativeElement.value = cleanVal;
     this.onChange(cleanVal);
   }
 }

pretty straight forward, takes a regex input, binds to the input event, and runs match on the value with the supplied regex which will remove any non allowed characters.

The confusing parts might be the the control value accessor parts... this just makes it compatible with form controls and ng model etc.

use like:

<input type="text" regexInput="[A-Za-z0-9]*">
bryan60
  • 28,215
  • 4
  • 48
  • 65
0

This will fail accessibility guidelines, you should take all keys pressed and then provide the user with an easy to understand validation error if any of the keys pressed are invalid for that input. Ignoring keys pressed is not allowed under accessibility guidelines.

Adrian Brand
  • 20,384
  • 4
  • 39
  • 60