Crowdpleasr
Crowdpleasr

Reputation: 4044

Use custom directive value to optionally display form element

I'm trying to use the output from a custom validation directive in one element <input> to control the display of another element <p>, but can't figure out how to make it work. This is what I have so far:

Custom Directive (no-special-chars-directive.ts)

import { Directive } from '@angular/core';
import { Validator, 
        FormControl, 
        NG_VALIDATORS, 
        ValidationErrors} from "@angular/forms";

@Directive({
  selector: '[appNoSpecialChars]',
  providers: [{provide: NG_VALIDATORS, useExisting: NoSpecialCharsDirective, multi: true}],
  exportAs: 'noSpecChars'
})
export class NoSpecialCharsDirective implements Validator{

  constructor() { }
  validate(c: FormControl): ValidationErrors {
    //console.log("input value: " + c.value);
    const hasSpecialChars = /[~!@#\^&*+=\-\[\]\';,/{}|\":<>\?\\()]/.test(c.value);
    const message = {
      'hasSpecialChars' : {
        'message': 'No Special Chars Allowed'
      }
    };
    return hasSpecialChars ? message : null;
  }
}

Here is the template: (git-search.component.html)

<h3>{{title}} - {{displayQuery}} -- (version: Template Driven)</h3>
<form #myForm="ngForm" (ngSubmit)="sendQuery()">
  <div *ngFor="let key of modelKeys">
      {{key}} 
      <input  #myInput name="{{key}}" placeholder="Enter {{key}} Here" [(ngModel)]="model[key]" required *ngIf="key==='q'" appNoSpecialChars/>
      <input  #myInput name="{{key}}" placeholder="Enter {{key}} Here" [(ngModel)]="model[key]" minlength = '2' maxlength='4' *ngIf="key==='stars'" appNoSpecialChars />      
      <input  #myInput name="{{key}}" placeholder="Enter {{key}} Here" [(ngModel)]="model[key]" *ngIf="key!=='q' && key!=='stars'" appNoSpecialChars/> 
      <p *ngIf="!myForm[key].valid" >Not valid</p> 
  </div>
  <button type="submit" [disabled]="!myForm.valid">Submit</button> 
</form>

I want the <p> element to optionally display whenever there is invalid input in the preceding <input>. I've tried multiple permutations for the *ngIf statement and in the inputs themselves, but haven't found anything that works yet. Everything worked fine before I started playing around with the optional display of the <p> element. Any ideas?

Upvotes: 0

Views: 35

Answers (1)

Arikael
Arikael

Reputation: 2085

Change the line

<p *ngIf="!myForm[key].valid" >Not valid</p>

to

<p *ngIf="!myForm.form.get(key)?.valid" >Not valid</p> 

myForm.form gets the default/in your case only FormGroup which holds all FormControls.

The ? is like a special null coalesce operator (Why we use "?" operator in template binding in angular 2) which prevents errors in case myForm.form.get(key) is NULL.

you can see it in action here https://stackblitz.com/edit/angular-liqgux

Upvotes: 1

Related Questions