3

I'm working with angular 5 reactive form. In that I have one browse field, On change event of that browse button I'm calling a function, in that file validation is checked. If file is invalid, I'm setting an error manually to that field.

Now what I'm expecting is when file input error is set. Error message should display in DOM. It's working fine with Chrome, Firefox and Android devices. But It is not working in IE and IOS.

HTML CODE

<div class="form-group" [ngClass]="{'has-error': hasError('profileimage')}">
   <label class="control-label"> Upload Profile Image...</label>
   <input id="profileimage" 
   (change)="fileUpload($event.target.files,'profileimage')" 
   type="file"
   formControlName="profileimage">
   <span class="is-error" *ngIf="checkValidImageFormat('profileimage')">
   Only file with extensions are allowed: .png, .jpeg, .jpg .</span>
   <span class="is-error" *ngIf="checkValidImageSize('profileimage')">File must be less than 1 MB .
   </span>
 </div>

Component.ts

fileUpload(files: FileList, field) {
  this.profileimage = files[0];
  let extension = this.profileimage.name.match(/(?:\.([^.]+))?$/)[1];
  //checking the extension of the file
  if (extension.toLowerCase() === 'jpg' ||
    extension.toLowerCase() === 'jpeg' ||
    extension.toLowerCase() === 'png') {

    var sizeInMB = (this.profileimage.size / (1024 * 1024)).toFixed(2);
    //checking the file size should be less than 1 mb
    if (!parseFloat(sizeInMB) < 1) {
      this.contactForm.controls[field].setErrors({ 'invalid_size': true });
  }
}

checkValidImageSize(fieldName) {
  return this.contactForm.controls[fieldName].errors.invalid_size;
}

I have tried all change detection strategies (NgZone, ChangeDetectorRef etc.) for angular but none of them worked. Any help would be appreciated.

Ushma Joshi
  • 459
  • 6
  • 19

1 Answers1

3

You can create attribute directive some thing like...

html (you must follow this order of html tags)

 <div class="form-group">
    <label class="control-label"> Upload Profile Image...</label>
    <input id="profileimage" checkinvalid (change)="fileUpload($event.target.files,'profileimage')" type="file"
      formControlName="profileimage">
    <span class="is-error">File must be less than 1 MB .</span>
    <span class="is-error">Only file with extensions are allowed: .png, .jpeg, .jpg .</span>
  </div>

component.ts (not necessary because you already get value in form control)

fileUpload(files: FileList, field) {
    this.profileimage = files[0];
}

directive.ts

parent: any;
spanForFormat: any;
spanForSize: any;

@HostListener('change', ['$event'])
handleChangeEvent(event) {
    const file = event.target.files[0];
    this.checkInvalid(file);
}

constructor(private elementRef: ElementRef, private renderer: Renderer2) { }

ngOnInit() {
    this.parent = this.elementRef.nativeElement['parentElement'];
    this.spanForSize = this.elementRef.nativeElement['parentElement'].children[2];
    this.spanForFormat = this.elementRef.nativeElement['parentElement'].children[3];
    this.renderer.addClass(this.spanForSize, 'hidden');
    this.renderer.addClass(this.spanForFormat, 'hidden');
}

private checkInvalid(file) {

    this.renderer.addClass(this.spanForSize, 'hidden');
    this.renderer.addClass(this.spanForFormat, 'hidden');
    this.renderer.removeClass(this.parent, 'has-error');

    let extension = file.name.match(/(?:\.([^.]+))?$/)[1];
    let sizeInMB = (file.size / (1024 * 1024)).toFixed(2);

    if (!(extension.toLowerCase() === 'jpg' ||
        extension.toLowerCase() === 'jpeg' ||
        extension.toLowerCase() === 'png')) {
        this.renderer.removeClass(this.spanForFormat, 'hidden');
        this.renderer.addClass(this.parent, 'has-error');
    }

    if (!(parseFloat(sizeInMB) < 1)) {
        this.renderer.removeClass(this.spanForSize, 'hidden');
        this.renderer.addClass(this.parent, 'has-error');
    }
}
R. Viral
  • 386
  • 1
  • 6
  • Above code not working on IE or not working on any browser. Let me share running example. **tested on IE11** [check running example](https://angular-btemcb.stackblitz.io/) – R. Viral Nov 28 '18 at 12:11
  • Oh, thanks, I have changed some code and It's working. – Ushma Joshi Nov 28 '18 at 13:34