Angular. After closing image cropper does not open the same image from another panel in accordion

983 Views Asked by At

In accordion content there is a functionality to upload cropped image. When I clicked the icon to upload it opens modal for image cropping, but when I close the modal instead of "Done" in second time for the same image it does not open the modal.

Html Input

<label [for]="'image-input-' + i">
  <span class="icon">
    <i class="fa-solid fa-circle-plus" title="Upload new image"></i>
  </span>
</label>

<input hidden #imageInput [id]="'image-input-' + i" type="file" accept="image/*"                               
      (change)="onFileChange($event, promotion.promotion,'image')" />

Cropper

<ng-template #ImageCropper let-modal>
    <div class="p-2 cropper">
        <h5 class="modal-title" id="exampleModalLabel">
            Crop Selected
            Image</h5>
        <image-cropper [maintainAspectRatio]="true"
            [aspectRatio]="6 / 3" format="png"
            [imageChangedEvent]="imageCropperEventAttached"
            (imageCropped)="ImageCropped($event)">
        </image-cropper>
    </div>
    <div class="d-flex">
        <button type="button"
            class="btn btn-danger text-white px-3 py-2 m-2 ms-auto"
            (click)="onThumbnailCropperCloseClick()">
            Close
        </button>
        <button type="button"
            class="btn btn-primary px-3 py-2 m-2"
            (click)="processFile(imageInput, selectedData, 'image')">
            Done
        </button>
    </div>
</ng-template>

typescript

onFileChange(event: any, pr: any, imgType: any): void {
    this.imageCropperEventAttached = event;
    this.popup = this.modalService.open(this.imageCropModel);
    this.selectedData = pr;
  }

I tried to add @ViewChild('imageInput') imageInput: ElementRef;

and set value null on closing but it does not work properly when I try to upload the same image from another panel .

onThumbnailCropperCloseClick() {
    this.popup.close();
    this.imageInput.nativeElement.value = '';
  }

Stackblitz

2

There are 2 best solutions below

0
Koryun On BEST ANSWER

Every time ViewChild returns the first panel because Angular will find the first instance of the panel. Change ViewChild to ViewChildren for getting all of the panels.

@ViewChildren('imageInput') imageInput: any;

And also set empty value to all panels in onThumbnailCropperCloseClick()

onThumbnailCropperCloseClick() {
    this.popup.close();
    this.imageInput.forEach((panel: ElementRef) => panel.nativeElement.value = '');
}
1
Nehal On

You have two options to address this issue.

  1. Force the user to take action by disabling backdrop dismiss.

  2. Listen to result event triggered, when user dismisses the modal without pressing a button.

onFileChange(event: any, data): void {
    console.log(event);

    this.imageCropperEventAttached = event;
    this.popup = this.modalService.open(this.imageCropModel);
    
    // option 1: force user to take action, by disabling backdrop dismiss
    // this.popup = this.modalService.open(this.imageCropModel, {backdrop: 'static', keyboard: false});
    this.selectedData = data;
    console.log(data);

    // option 2: listen to result event emitted from modal dismiss
    this.popup.result.then(() => {}, () => this.onThumbnailCropperCloseClick());
  }

Stackblitz demo