14

ngControl with a value of new Control('', Validators.required) didn't work even when the file is valid.

(and actually, I found it difficult to validate radio buttons as well...)

4
  • 1
    self-solved. html <input type="file" (change)="onChange($event)"> ts controlName.updateValue(value) (value is set via FileReader) Commented Jan 22, 2016 at 12:39
  • hey @Yusu can you answer you own question and provide all relevant code which worked for you...?? Commented Mar 23, 2016 at 8:54
  • @YuSu Can you indeed please provide all relevant code, cause I'm not able to do it as you tell. If I try with this.frm.patchValue({ file: evt.target.value }); I'm getting: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string. Commented Jan 26, 2017 at 15:17
  • Check my answer here for a full working example + explanation Commented Aug 17, 2017 at 10:58

3 Answers 3

5

Validators.required depends on the value of the field.

Input type file does not have a value, therefore is considered as undefined or null.

That is why it is invalid. Better write you own validation.

For custom file validation example refer

Sign up to request clarification or add additional context in comments.

Comments

1

An example of validator to use with the normal require attribute could be something like this

import { Provider, forwardRef, Directive } from '@angular/core';
import { NG_VALIDATORS, Validator, Control } from '@angular/common';
export const NO_ATTACHMENT_VALIDATOR = new Provider(NG_VALIDATORS,{
  useExisting: forwardRef(() => noAttachmentValidator ),
  multi: true
});

@Directive({
  selector: '[noAttachmentValidator][ngControl],[noAttachmentValidator][ngFormControl],[noAttachmentValidator][ngModel]',
  providers: [NO_ATTACHMENT_VALIDATOR]
})

export class noAttachmentValidator implements Validator{
  public validate(control: Control) : { required: { [key: string]: boolean } | null } {
    let state,
        value = control.value,
        alreadyUsed = control.dirty;

    if(alreadyUsed && value.length == 0){
      state = true;
    }
    return state ? { required : { 'required' : false } } : null
  }
}

Basically required attribute is checking the first time, this every time after that you have used the input the first time,even if you remove the file (that was my problem ) cause the control of the value is for null. And when it's untouched it's null,then it's become filled when you add a file, but if you remove it it's just an empty array so [] !== null . I hope this helps follow this you can build you own type of validation if you need to.

Comments

0

One great solution to resolve this issue is to create a custom element which wrap your and implements a ValueAccessor. This way you can create a custom component which works exactly like the other form's elements. Instead of using the input value you can use another variable inside your component.

More information here : Applying angular2 form directives to custom input form elements

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.