简体   繁体   中英

Mark required formControls before Validation when using Reactive Forms in Angular 5

We would like to give visual feedback to the user, which field is required, before validation, eg by highlighting the field blue.

We are using Reactive Forms to validate the user's input:

export class MyFormComponent {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.myForm = fb.group({
      name: ['', Validators.required ],
      city: ''
    });
  }
}

with the template

<form [formGroup]="myForm">
  <div class="form-group">
    <label>Name:
      <input class="form-control" formControlName="name">
    </label>
  </div>
  <div class="form-group">
    <label>City:
      <input class="form-control" formControlName="name">
    </label>
  </div>
</form>

The whole template will be generated from a model later on. Because of this, we would like to keep the template as "pure" as possible.

But: For highlighting required fields via CSS, I need either a class or an attribute ( required ) on the input-element. It would be nice, if Angular could set one (or both) to the input -Element, when the corresponding FormControl is given an Validator of required .

In the above example, I would have to add a class required or the attribute required by hand to the input -Element to make this CSS work:

.form-control[required], .form-control.required {
  border-color: blue;
}

Is there a way to attach class or attribute to the DOM-Element automatically, when a validator is set to the corresponding FormControl ?

So angular does not have anything called as getValidators. There is an open issue here https://github.com/angular/angular/issues/13461

However, here is something you can do to get all formControls with the required validator. (Not my code: Mentioned by someone on the open issue)

getValidators(_f) {
  return Object.keys(_f).reduce((a, b) => {
    const v = _f[b][1];
    if (v && (v === Validators.required || v.indexOf(Validators.required) > -1)) {
      if (!a[b]) { a[b] = {}; }
      a[b]['required'] = true;
    }
    return a;
  }, {});
}

const _f = {
  id: [],
  name: [null, Validators.required],
  phone: [],
  email: [null, [Validators.required, Validators.email]]
};
this.frmMain = this._fb.group(_f);
console.log(this.getValidators(_f));    // {name: {"required": true}, email: {"required": true}}

Once you have the list of all controls with the required validator, you can just loop through them and apply styles accordingly.

I hope the only issue was getting controls with required validator? If yes, this should resolve the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM