2
votes

I have a need to inspect each of the form controls (input, textarea, etc.) in a form to read which type of element they are. I have a vast number of forms, and want to automate setting of different (default) validators for each type of form element. I don't want to have to list out every possible formControlName somewhere to define what type they are, so thought I could just inspect the HTML for that instead.

My thought was to either get them all using some query selector that returns all elements with formControlName present, or I could loop through the form names that should be present, and get each item with a query selector the tests the names against the formControlName attribute.

So if I have a form that looks like:

<form novalidate [formGroup]="formGroup">

  <div class="row">
    <div class="group-label">Street</div>
    <input type="text" class="form-control" formControlName="street">
    <div class="group-label">City</div>
    <input type="text" class="form-control" formControlName="city">
    <div class="group-label">State</div>
    <input type="text" class="form-control" formControlName="state">
    <div class="group-label">Some Description</div>
    <div class="nested">
        <textarea class="form-control" formControlName="description"></textarea>
    </div>
  </div>

</form>

And a FormGroup that looks like:

this.formGroup = this.formBuilder.group({
  street: [addr ? addr.street : ''],
  city: [addr ? addr.city : ''],
  state: [addr ? addr.state : ''],
  description: [addr.description ? addr.description : ''],
});

I would think I should be able to loop through the group, and find a form element matching each of the keys, inspect its tag name, and set validators based on weather the element is a textarea or input.

This is a waaay simplified example, because I'm automating building the formGroups in a separate class, but it should get the point across.

What is the proper way to do something like this in Angular, if any, and are they security issues from doing such a thing?

1
Can you add an example FormGroup and template? Then explain what you are trying to do.sabithpocker
@sabithpocker I added an example.BBaysinger
I can think of a custom attribute directive to use in your HTML wherever the validation need to be applied. <input apply-validation type="text"/>. You will have to still add this in HTML whenever an element needs validation. You can also extend this in different ways.sabithpocker
Hm, yeah. I already have a directive on each of my form elements, so I guess they could each register themselves somewhere they can be accessed.BBaysinger
I should have though of that. Jeez.BBaysinger

1 Answers

1
votes

Try some directive like

import { Directive, ElementRef, HostListener } from "@angular/core";
import { NgControl } from "@angular/forms";

@Directive({
  selector: '[apply-validtion]'
})
export class ApplyValidation {
  constructor(private el: ElementRef, private control : NgControl) { 
    let type = this.el.nativeElement.tagName;
    switch(type) {
        case 'input': this.control.control.setValidators([]); break;
        case 'textarea': this.control.control.setValidators([]); break;
        default: this.control.control.setValidators([]);
    }
  }
}