0

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

bayandur
  • 13
  • 2

2 Answers2

2

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 = '');
}
Koryun
  • 58
  • 1
  • 8
0

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

Nehal
  • 13,130
  • 4
  • 43
  • 59
  • In case of option 1 there is a strange behavior. On clicking close it does not close. Option two also doesn't work properly. I open second panel and after cropping I close the modal 2 times. That works. After that I open the third panel and try the same thing two times. And it does not work. – bayandur Jul 17 '22 at 21:07