如何使此表单验证适用于自定义文件上传字段

时间:2019-04-21 03:40:23

标签: angular

在以下反应形式中,如果出现错误,我会在输入字段周围添加一个红色边框。错误是当这些字段保留为空并且用户单击提交按钮时,或者当用户将注意力集中在输入字段上而没有输入任何内容而移出时。 观看此演示,您将了解我的意思(在输入字段上按Tab键,因为触摸了它,它留空了,它将显示红色边框)-https://stackblitz.com/edit/angular-ynkf5j

当我创建一个自定义上传字段时,同样的事情变得棘手,为了自定义,我们需要隐藏真实文件输入-DEMO https://stackblitz.com/edit/angular-fqzszn 当我们单击提交而不输入任何内容时,错误边框会添加到文件输入中,因为此处没有涉及任何内容,但是第二种情况(cForm.controls.file.errors?.required && cForm.controls.file.touched)无法正常工作。

我需要找到一种方法来克服这个问题。我们可以使它感动还是有其他方法可以做到这一点。

  <form [formGroup]="cForm" (ngSubmit)="onSubmit()">
      <input type=text placeholder="name" formControlName="name"
      [ngClass]="{'err-border': (cForm.controls.name.errors?.required && cForm.controls.name.touched) || cForm.controls.name.errors?.required && submitted}" 
      >
      <br><br><br>
      <input type="file" formControlName="file" id="realInput" style="display: none">
      <button id="fakeBtn"
      [ngClass]="{'err-border': (cForm.controls.file.errors?.required && submitted) || (cForm.controls.file.errors?.required && cForm.controls.file.touched)}"
      >Upload</button>
      <span id="text">No file selected</span>
      <br><br><br>
      <button type="submit" >Submit</button>
    </form>

TS文件

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  cForm: FormGroup;
  submitted = false;
  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.cForm = this.formBuilder.group({
      name: ['', Validators.required],
      file: ['', Validators.required]
    });
    var realInput = document.querySelector('#realInput');
    var fakeBtn = document.querySelector('#fakeBtn');
    var text = document.querySelector('#text');
    fakeBtn.addEventListener("click", function(){
       // @ts-ignore
      realInput.click();

       })
       realInput.addEventListener("change", function(event) {
       // @ts-ignore
      if(realInput.value) {
         // @ts-ignore
        text.innerHTML = event.target.files[0].name;
      } else {
          text.innerHTML = "No file selected";
      }
       });

  }
onSubmit() {
  this.submitted = true;
  if(this.cForm.invalid) {
    return;
  }
  console.log(this.cForm.value);
}

}

1 个答案:

答案 0 :(得分:0)

您需要的事件是焦点事件,这时我们将按钮标记为已触摸,您的现有验证将从那里接管...我们通过对代码进行2次更改来做到这一点

在您的 app.component.ts 中,已添加:

focusFunction(){
  this.cForm.controls.file.markAsTouched(); 
}

对app.component.html中的#fakeBtn进行一项更改:

<button id="fakeBtn"
  [ngClass]="{'err-border': (cForm.controls.file.errors?.required && submitted) || (cForm.controls.file.errors?.required && cForm.controls.file.touched)}"
  (focus)="focusFunction()"
  >Upload</button>

完成demo from your forked code is here