Ionic 4 - buttons in modal not firing click on Safari mobile

Hi,
I have been working on an Ionic 4 app based on ngx-rocket. The framework is really impressive (both Ionic and ngx-rocket) and nice to work with, however for the past week I’ve been wasting time on a small problem that stops my progress, and I have no clue as to its solution. This problem halts all development and I need to figure it out fast.

I have a Modal window with an angular-cropper element and a toolbar with ‘dismiss’ and ‘apply’ buttons. 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 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. 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 works 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.

What am I missing? Is there a module I’m not importing?
Is it an Ionic syntax error by my part?
Is this a bug in the framework, since it only happens on iPhone devices (not even safari)?

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 code for opening the modal:

 async cropBanner(ev: any) {
        const modal = await this.modal.create({
            component: ModalImageCropComponent,
            componentProps: {
                event: ev,
                ratio: 310.0 / 80.0
            },
            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
  ]
})

Please help,
Thanks!

Just a few idea I would have spontaneously

  1. If you remove the cropper, does the actions fire?
  2. If you remove all css, does the actions fire?

If one of these works, then it’s maybe a problem of css, like z-index or something.

If not, did you debug the console output in safari (I mean when you are testing your iPhones and you pair safari, did you see an error in the console output)?

Finally, I don’t know what you do with the ratio parameter, in case you change the size of the modal, could that be a hint too?

Like I said, just a couple of ideas, not sure it helps but I hope at least a bit

Thanks for the reply,
Yes, removing the cropper makes the buttons work again, as stated.
The ratio is an argument for the cropper’s crop area, I do no resizing in the modal.
There is no css in the component, and I’ve tried all form of css positioning I can think of.
Buttons are there and clickable , but not working.:confused:

Try to set a z-index -1 to your cropper or a hight z-index to your buttons, does that help?

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 StackOverflow post: angular-2-4-add-compiled-component-to-an-iframe. It needed some tweaking to the iFrame’s styling but did the trick.

For cropperjs you could also just use it without any angular binding. In my project I just use cropperjs and added the @type/cropperjs and here we go