Search code examples
javascriptangularmobile-safariionic4cropperjs

Ionic4 / mobile Safari - Buttons on modal are not firing click event if angular-cropper component is present


I'm working on an Ionic 4 app based on ngx-rocket starter kit.

I have a Modal window with an angular-cropper element and a toolbar with ‘dismiss’ and ‘apply’ buttons.

Here is the modal’s html:

<ion-header color="c-dark-gray" no-border>
    <ion-toolbar no-padding color="c-dark-gray">
        <ion-buttons slot="start">
            <ion-button fill="clear" no-margin no-padding text-center (click)="dismiss()">
                <ion-icon slot="icon-only" name="close" color="light"></ion-icon>
            </ion-button>
        </ion-buttons>

        <ion-title translate color="light">Move and Scale</ion-title>

        <ion-buttons slot="end">
            <ion-button fill="clear" no-padding no-margin (click)="apply()">
                <ion-text translate color="c-orange" text-uppercase>Apply</ion-text>
            </ion-button>
        </ion-buttons>
    </ion-toolbar>
</ion-header>

<ion-content color="c-dark-gray">
    <ion-grid no-padding no-margin>
        <ion-row>
            <ion-col no-padding no-margin>
                    <angular-cropper
                        #cropper
                        *ngIf="_image"
                        [cropperOptions]="_cropperjsSettings"
                        [imageUrl]="_image"
                        [ngClass]="{'round-cropper': _round}"></angular-cropper>
            </ion-col>
        </ion-row>
    </ion-grid>
</ion-content>

THE PROBLEM: Everything works great in Android and on browsers (chrome, FF and safari), but only on Safari on iPhone devices (tested on 5,7,8+), the buttons don’t fire the click event. Actually, any button or clickable element I place on the modal page, in header, footer, toolbar or in the content, above, below the cropper, or even absolute positioned overlay on top of it, does not work, and only on iPhone devices (Safari). The cropper element on the modal is working fine.

FURTHERMORE, the buttons are accessible and clickable - they interact visually with the click, and in the inspector I can see classes shift on the button elements when clicking on them. But for some reason, no click events are sent to the app, and the click handlers are not running. If I remove the angular-cropper element, buttons work fine.

I’ve tried converting the modal into a popover, but had similar results (buttons not firing click events). The one thing I haven’t tried is setting up a full blown routed page for the crop, but this is not an acceptable solution, design wise.

I’ve also created a small ionic side menu test app with a similar page and modal, but everything works great there, so this is not an issue with the cropper not being supported by Ionic on a modal. Note that this whole gadget worked fine in V3. Problem happens on latest Ionic4.

What am I missing? Is there a module I’m not importing? Any idea, or clue is welcomed.

The code for opening the modal:

 async cropBanner(ev: any) {
        const modal = await this.modal.create({
            component: ModalImageCropComponent,
            componentProps: {
                event: ev,
                ratio: 3 /4
            },
            showBackdrop: false
        });

        modal.onDidDismiss()
            .then((evMod: OverlayEventDetail<any>) => {
                this._bannerInput.getInputElement()
                    .then((val: HTMLInputElement) => {
                        log.debug('resetting input');
                        val.value = null;
                    });
            });
        await modal.present();
}

And the modal’s ngModule declaration:

@NgModule({
  declarations: [
    ModalImageCropComponent
  ],
  exports: [
    ModalImageCropComponent
  ],
  entryComponents: [
    ModalImageCropComponent
  ],
  imports: [
    CommonModule,
    IonicModule,
    AngularCropperjsModule
  ]
})

packages:

ionic info

Ionic:

   ionic (Ionic CLI) : 4.10.3

System:

   NodeJS : v10.15.1
   npm    : 6.8.0
   OS     : macOS High Sierra

ng version

Angular CLI: 7.3.1
Node: 10.15.1
OS: darwin x64
Angular: 7.2.4

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.13.1
@angular-devkit/build-angular     0.13.1
@angular-devkit/build-optimizer   0.13.1
@angular-devkit/build-webpack     0.13.1
@angular-devkit/core              7.3.1
@angular-devkit/schematics        7.3.1
@angular/cli                      7.3.1
@ngtools/webpack                  7.3.1
@schematics/angular               7.3.1
@schematics/update                0.13.1
rxjs                              6.4.0
typescript                        3.2.4
webpack                           4.29.0

npm list | grep ionic

├─┬ @ionic-native/core@5.0.0
├─┬ @ionic-native/splash-screen@5.0.0
├─┬ @ionic-native/status-bar@5.0.0
├─┬ @ionic/angular@4.0.2
│ ├─┬ @ionic/core@4.0.2
│ │ └── ionicons@4.5.5
├─┬ @ionic/v4-migration-tslint@1.7.0
├── cordova-plugin-ionic-keyboard@2.1.3
├── cordova-plugin-ionic-webview@3.1.2

Solution

  • After a bit more digging, I still have no clue as to why buttons on the modal are not working on Safari, but I suspect the outdated angular-cropperjs package does not handle V4 shadow DOM properly. I considered updating the package myself, but have no resources for it.

    SOLUTION: Workaround was to dynamically place the angular-cropperjs element in an iFrame, according to this SO post: angular-2-4-add-compiled-component-to-an-iframe. It needed some tweaking to the iFrame's styling but did the trick.