[angular] How to validate white spaces/empty spaces? [Angular 2]

I would like to avoid white spaces/empty spaces in my angular 2 form? Is it possible? How can this be done?

This question is related to angular validation typescript input

The answer is


To avoid the form submition, just use required attr in the input fields.

<input type="text" required>

Or, after submit

When the form is submited, you can use str.trim() to remove white spaces form start and end of an string. I did a submit function to show you:

submitFunction(formData){

    if(!formData.foo){
        // launch an alert to say the user the field cannot be empty
        return false;
    }
    else
    {
        formData.foo = formData.foo.trim(); // removes white 
        // do your logic here
        return true;
    }

}

To validate white space in starting in an input you can just call change event and do inline function for that.

_x000D_
_x000D_
<input type="text" class="form-control"                     
            placeholder="First Name without white space in starting"
            name="firstName"
            #firstName="ngModel"
            [(ngModel)]="user.FirstName"
            (change) ="user.FirstName = user.FirstName.trim()"
            required/>
_x000D_
_x000D_
_x000D_


i have used form valueChanges function to prevent white spaces. every time it will trim all the fields after that required validation will work for blank string.

Like here:-

this.anyForm.valueChanges.subscribe(data => {
   for (var key in data) {
        if (data[key].trim() == "") {
          this.f[key].setValue("", { emitEvent: false });
        }
      }
    }

Edited --

if you work with any number/integer in you form control in that case trim function will not work directly use like :

this.anyForm.valueChanges.subscribe(data => {
  for (var key in data) {
        if (data[key] && data[key].toString().trim() == "") {
          this.f[key].setValue("", { emitEvent: false });
        }
      }  
  }

In your app.component.html

<form [formGroup]="signupForm">

           <input  type="text" name="name" [formControl]="signupForm.controls['name']"
              placeholder="First Name"
              required
            />
     <small
            *ngIf="signupForm.controls['name'].hasError('pattern')"
            class="form-error-msg"
            >First Name without space</small>

    </form>

In your app.componen.ts file

import { Validators, FormGroup, FormControl } from "@angular/forms";
signupForm: FormGroup;
ngOnInit(){
this.signupForm = new FormGroup({
  name: new FormControl("", [
    Validators.required,
    Validators.pattern("^[a-zA-Z]+$"),
    Validators.minLength(3)
  ])
})

I had a requirement where in the Firstname and Lastname are user inputs which were required fields and user should not be able to hit space as the first character.

Import AbstractControl from node_modules.

import { AbstractControl } from '@angular/forms';

check if the first character is space If yes then blank the value and return required: true. If no return null

export function spaceValidator(control: AbstractControl) {
if (control && control.value && !control.value.replace(/\s/g, '').length) {
    control.setValue('');
    console.log(control.value);
    return { required: true }
}
else {
    return null;
}
}

the above code will trigger an error if the first character is space and will not allow space to be the first character.

And in form builder group declare

this.paInfoForm = this.formBuilder.group({
        paFirstName: ['', [Validators.required, spaceValidator]],
        paLastName: ['', [Validators.required, spaceValidator]]
})

In hello.component.html

<input [formControl]="name" />
<div *ngIf="name.hasError('trimError')" > {{ name.errors.trimError.value }} </div>

In hello.component.ts

import { ValidatorFn, FormControl } from '@angular/forms';

const trimValidator: ValidatorFn = (text: FormControl) => {
  if (text.value.startsWith(' ')) {
    return {
      'trimError': { value: 'text has leading whitespace' }
    };
  }
  if (text.value.endsWith(' ')) {
    return {
      'trimError': { value: 'text has trailing whitespace' }
    };
  }
  return null;
};`

export class AppComponent {
  control = new FormControl('', trimValidator);
}

Example Code


    export function noWhitespaceValidator(control: FormControl) {
       const isSpace = (control.value || '').match(/\s/g);
       return isSpace ? {'whitespace': true} : null;
}

to use

 password: ['', [Validators.required, noWhitespaceValidator]]

In template/html

<span *ngIf="newWpForm.get('password').hasError('whitespace')">
    password cannot contain whitespace
</span>

After lots of trial i found [a-zA-Z\\s]* for Alphanumeric with white space

Example:

New York

New Delhi


If you are using Angular Reactive Forms you can create a file with a function - a validator. This will not allow only spaces to be entered.

import { AbstractControl } from '@angular/forms';
export function removeSpaces(control: AbstractControl) {
  if (control && control.value && !control.value.replace(/\s/g, '').length) {
    control.setValue('');
  }
  return null;
}

and then in your component typescript file use the validator like this for example.

this.formGroup = this.fb.group({
  name: [null, [Validators.required, removeSpaces]]
});

If you are using reactive forms in Angular 2+, you can remove leading and trailing spaces with the help of (blur)

app.html

<input(blur)="trimLeadingAndTrailingSpaces(myForm.controls['firstName'])" formControlName="firstName" />

app.ts

public trimLeadingAndTrailingSpaces(formControl: AbstractControl) {
    if (formControl && formControl.value && typeof formControl.value === 'string') {
        formControl.setValue(formControl.value.trim());
    }
}

Following directive could be used with Reactive-Forms to trim all form fields so standart Validators.required work fine:

@Directive({
  selector: '[formControl], [formControlName]',
})
export class TrimFormFieldsDirective {
  @Input() type: string;

  constructor(@Optional() private formControlDir: FormControlDirective, 
              @Optional() private formControlName: FormControlName) {}

  @HostListener('blur')
  @HostListener('keydown.enter')
  trimValue() {
    const control = this.formControlDir?.control || this.formControlName?.control;
    if (typeof control.value === 'string' && this.type !== 'password') {
      control.setValue(control.value.trim());
    }
  }
}

I think a simple and clean solution is to use pattern validation.

The following pattern will allow a string that starts with white spaces and will not allow a string containing only white spaces:

/^(\s+\S+\s*)*(?!\s).*$/

It can be set when adding the validators for the corresponding control of the form group:

const form = this.formBuilder.group({
            name: ['', [
                Validators.required,
                Validators.pattern(/^(\s+\S+\s*)*(?!\s).*$/)
            ]]
        });

To automatically remove all spaces from input field you need to create custom validator.

removeSpaces(c: FormControl) {
  if (c && c.value) {
    let removedSpaces = c.value.split(' ').join('');
    c.value !== removedSpaces && c.setValue(removedSpaces);
  }
  return null;
}

It works with entered and pasted text.


This is a slightly different answer to one below that worked for me:

_x000D_
_x000D_
public static validate(control: FormControl): { whitespace: boolean } {_x000D_
    const valueNoWhiteSpace = control.value.trim();_x000D_
    const isValid = valueNoWhiteSpace === control.value;_x000D_
    return isValid ? null : { whitespace: true };_x000D_
}
_x000D_
_x000D_
_x000D_


Prevent user to enter space in textbox in Angular 6

<input type="text" (keydown.space)="$event.preventDefault();" required />

What I did was created a validator that did the samething as angular for minLength except I added the trim()

import { Injectable } from '@angular/core';
import { AbstractControl, ValidatorFn, Validators } from '@angular/forms';


@Injectable()
export class ValidatorHelper {
    ///This is the guts of Angulars minLength, added a trim for the validation
    static minLength(minLength: number): ValidatorFn {
        return (control: AbstractControl): { [key: string]: any } => {
            if (ValidatorHelper.isPresent(Validators.required(control))) {
                return null;
            }
             const v: string = control.value ? control.value : '';
            return v.trim().length < minLength ?
                { 'minlength': { 'requiredLength': minLength, 'actualLength': v.trim().length } } :
                null;
        };
    }

    static isPresent(obj: any): boolean {
        return obj !== undefined && obj !== null;
    }
}

I then in my app.component.ts overrode the minLength function provided by angular.

import { Component, OnInit } from '@angular/core';    
import { ValidatorHelper } from 'app/common/components/validators/validator-helper';
import { Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {  
  constructor() { }

  ngOnInit(): void {       
    Validators.minLength = ValidatorHelper.minLength;
  }
}

Now everywhere angular's minLength built in validator is used, it will use the minLength that you have created in the helper.

Validators.compose([
      Validators.minLength(2)         
    ]);

You can create a custom validator to handle this.

new FormControl(field.fieldValue || '', [Validators.required, this.noWhitespaceValidator])

Add noWhitespaceValidator method to your component

public noWhitespaceValidator(control: FormControl) {
    const isWhitespace = (control.value || '').trim().length === 0;
    const isValid = !isWhitespace;
    return isValid ? null : { 'whitespace': true };
}

and in the HTML

<div *ngIf="yourForm.hasError('whitespace')">Please enter valid data</div>

An alternative would be using the Angular pattern validator and matching on any non-whitespace character.

const nonWhitespaceRegExp: RegExp = new RegExp("\\S");

this.formGroup = this.fb.group({
  name: [null, [Validators.required, Validators.pattern(nonWhiteSpaceRegExp)]]
});

Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to validation

Rails 2.3.4 Persisting Model on Validation Failure Input type number "only numeric value" validation How can I manually set an Angular form field as invalid? Laravel Password & Password_Confirmation Validation Reactjs - Form input validation Get all validation errors from Angular 2 FormGroup Min / Max Validator in Angular 2 Final How to validate white spaces/empty spaces? [Angular 2] How to Validate on Max File Size in Laravel? WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to typescript

TS1086: An accessor cannot be declared in ambient context Element implicitly has an 'any' type because expression of type 'string' can't be used to index Angular @ViewChild() error: Expected 2 arguments, but got 1 Typescript: No index signature with a parameter of type 'string' was found on type '{ "A": string; } Understanding esModuleInterop in tsconfig file How can I solve the error 'TS2532: Object is possibly 'undefined'? Typescript: Type 'string | undefined' is not assignable to type 'string' Typescript: Type X is missing the following properties from type Y length, pop, push, concat, and 26 more. [2740] Can't perform a React state update on an unmounted component TypeScript and React - children type?

Examples related to input

Angular 4 - get input value React - clearing an input value after form submit Min and max value of input in angular4 application Disable Button in Angular 2 Angular2 - Input Field To Accept Only Numbers How to validate white spaces/empty spaces? [Angular 2] Can't bind to 'ngModel' since it isn't a known property of 'input' Mask for an Input to allow phone numbers? File upload from <input type="file"> Why does the html input with type "number" allow the letter 'e' to be entered in the field?