Template Driven Forms required allows empty string - Angular 7/8

I'm having an issue with my form validation allowing empty strings. required works but allows the user to click space. the solution I found online works which is to use ng-pattern pattern=".*[^ ].*" but for some reason it does nor work with textarea. if the user copys and paste a an html page ng pattern throws an error. the weird thing is when I change the textarea to an input field it works fine. What's the correct solution to fix this. it allows the user to paste certain things but I can't pinpoint what is causing the error when I copied my whole html page and pasted it the textarea for testing. it seems like the spacing inbetween is causing it. StackBlitz: https://stackblitz.com/edit/angular-nhvgf1?file=src/app/hero-form/hero-form.component.html

this is what I pasted in the textarea which should not throw an error: <button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button> <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button> <i>with</i> reset

 <form (ngSubmit)="onSubmit()" #heroForm="ngForm">
  <div class="form-group">
    <label for="name">Name</label>
    <textarea type="text" class="form-control" id="name"
           required
            pattern=".*[^ ].*"
           [(ngModel)]="model.name" name="name"
           #name="ngModel"></textarea>
    <div [hidden]="name.valid || name.pristine"
         class="alert alert-danger">
      Name is required
    </div>
  </div>


  <button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
  <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
  <i>with</i> reset

  &nbsp;&nbsp;
  <button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>
  <i>without</i> reset

</form>

you can use this pattern for your purpose "(\s*[^\s]+\s*)+"

Validators.email should allow null/empty values · Issue #16183 , Styling of the template-driven forms example is all done with Bootstrap 4 CSS. Validation is implemented using the attributes required, minlength and I did it this way because I think it makes the template a bit cleaner and to check that two fields match export function MustMatch(controlName: string,  Template-driven Forms. Template-driven forms can be used for many applications i.e. log in, submit a request, place an order, data entry etc. Now, let's create the form. Follow these steps: Create a project. First, create a new project named angular-forms by using the following command:

you can just create a custom validator and this reusable approach

export class StrictRequiredDirective  implements Validator {
  validator: ValidatorFn;

  constructor() {
    this.validate = this.isStrictRequired();
  }
  validate(c: FormControl) {
    return this.validate(c);
  }

  isStrictRequired() :ValidatorFn{
    return (c: AbstractControl) => {
      console.log(c.value)
      if (c.value && String(c.value).trim()) {
        return null
      } else {
        return {strictRequired : true}
      }
    }
  }

}

stackblitz demo ⚡⚡

Angular 7, How to Validate Angular Template-Driven Forms AbstractControl): { [key: string​]: any } => { if (!control.value) { return null; } const regex = new RegExp('^(?=. required> <span class="text-danger" *ngIf="(name.touched  Template-driven forms are suitable for small or simple forms, while reactive forms are more scalable and suitable for complex forms. For a comparison of the two approaches, see Introduction to Forms You can build almost any kind of form with an Angular template—login forms, contact forms, and pretty much any business form.

Try to use this pattern \S+.*

It allows the user to use space BUT it won't be valid (if its only spaces):

ONLY SPACES IS NOT VALID IN THIS CASE!

This answer is only to match your initial request, but still I think that trimming this for the user can be a better User Experience.

To use a trimmer directive you can use this:

import { ElementRef, HostListener } from '@angular/core';
import { Output, EventEmitter, Renderer2 } from '@angular/core';
import { Directive, Input } from '@angular/core';

@Directive({
  selector: '[forceTrim]'
})
export class TrimDirective {

  @Output() ngModelChange = new EventEmitter();
  constructor(
    private _renderer: Renderer2,
    private _elementRef: ElementRef) {
  }

  @HostListener("input", ["$event.target.value"])
  handleInput(inputValue: any): void {

      const valueToProcess = inputValue.trim();
      this._renderer.setProperty(this._elementRef.nativeElement, "value", valueToProcess);
      this.ngModelChange.emit(valueToProcess);

  }
}

and in template use:

    <input
      type="text"
      forceTrim
    />

How to Validate Angular Template-Driven Forms, To add validation to a template-driven form, you add the same validation The <​input> element carries the HTML validation attributes: required and minlength . string; validate(control: AbstractControl): {[key: string]: any} | null { return this. Some field values might also depend on others; a user might be allowed to  Template Driven Forms required allows empty string - Angular 7/8 Hot Network Questions Do fresh chilli peppers have properties that ground chilli peppers do not?

An easy and reliable solution, is simply to add your form as a parameter, to onSubmit, and then do an additional check at the beginning of your onSubmit function.

HTML

<form (ngSubmit)="onSubmit(heroForm)" #heroForm="ngForm">
  <div class="form-group">
    <label for="name">Name</label>
    <textarea type="text" class="form-control" id="name"
           required
            pattern=".*[^ ].*"
           [(ngModel)]="model.name" name="name"
           #name="ngModel"></textarea>
    <div [hidden]="name.valid || name.pristine"
         class="alert alert-danger">
      Name is required
    </div>
  </div>


  <button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
  <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
  <i>with</i> reset

  &nbsp;&nbsp;
  <button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>
  <i>without</i> reset

</form>

TYPESCRIPT

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

... 

onSubmit(theForm: NgForm) {
  if(theForm.controls.name.value.trim() == '') {handleErrors(theForm, 1); return;}
  ... the rest of your onSubmit Code.
}

handleErrors(theForm: NgForm, errorCode: number) {
  switch (errorCode) {
    case 1:
      console.log("Empty textarea.");
      theForm.controls.name.setError({Empty_Textarea: true});
    return;
    default:
      console.log("Unhandled error"); 
    return;
  }
}

Validating form input, Angular makes the process easy by handling many of the repetitive, boilerplate export class Hero { constructor( public id: number, public name: string, public power: Because template-driven forms are in their own module, you need to add the If you arrive in this component with a new (blank) hero or an invalid hero,  Template-Driven Forms Validation App Module. There isn't much going on in the app module other than the standard stuff, the main thing you need to remember for using template-driven forms in Angular is to import the FormsModule from '@angular/forms' and include it in the imports array of the @NgModule decorator.

Template-driven forms, So although it's created a top-level FormGroup , it's empty. In template-driven forms we need Angular to create the model form controls for us for each First we add a string property called email on our component so we have somewhere The ngForm directive makes the top-level FormGroup available to us via its form  A quick example of how to implement validation in Angular 8 using Template-Driven Forms. The example is a simple registration form that validates on submit, includes a custom validator that validates password & confirm password fields match, and includes required checkbox validation.

Template-Driven Forms • Angular, In this guide, we will be exploring the Angular template-driven form validation. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <input id="employee" name=" the input tag contains the validation attributes like required and minlength. ValidatorFn { return (control: AbstractControl): {[key: string]: any} | null  Angular Template-driven Forms is one of the two ways of building forms in Angular. In this tutorial, we will learn how to build a simple Template-driven forms example app. First, we build a simple HTML form using a few form elements. The ngForm directive will convert it to the Template-driven form and create the top-level FormGroup control.

Validating Angular Template Driven Forms, The FormControl object gives information about that field. So to add validation to an Angular form we need two things: In template-driven forms, we apply the ngModel directive for every field in the template. static usernameShouldBeValid(control: AbstractControl): ValidationErrors | null { if ((​control.value as string). Introduction In this article, we will learn about validations in Angular template-driven forms. We will create a simple user registration form and implement some inbuilt validations on it. Along with the inbuilt validations, we will also implement some custom validations for the template-driven form. We will consider the following custom validations for this demo: * Checking for user name

Comments
  • 'required works well but if the user clicks the space button the form accepts it.' do you wish to keep this space? it is sometimes better to trim() it since a space at start is useless.
  • as long as the field isn't empty. the issue is space and nothing else
  • That seems to work @AndrewAllen running some test now you mind explaining.
  • it works it the stackblitz but for some odd reason it freezes my local app
  • You ask for empty but having a space is NOT empty... Again, it is better sometimes to trim the starting space immediately since it is useless.
  • When I copied my html page into the input it threw an error
  • looks like its working running some test nows
  • do you know how to make ng-pattern conditional like: pattern="condition ? '(\s*[^\s]+\s*)+' : ''"
  • Thanks I was trying to avoid having to make a custom directive since it's a minor issue. I would think form validation should have a simpler solution. or maybe a simple function to throw and error if the field is empty
  • In the stackblitz I tested it by copying my html page in there and it threw and error. It may be best to go that trim route you sugested
  • trying to avoid using a custom directive but @az264's answer worked well but I still voted so you can break 100 lol
  • Thanks I will test it out
  • But what about showing the red error so the user will know
  • @Flash I've amended my answer to include an error handler.
  • Appreciate but @ax264's answer worked best for me