Search code examples
angularjsnativescript

Nativescript angular preventing modal closing on background tap


I am pretty new to NativeScript but want to be able to prevent a custom modal that I have created from being closed when a user taps on the background, specifically for Android devices.

I can accomplish this pretty easily when using the provided dialogs from NativeScript i.e. for an action dialog can simply do this by setting cancelable to false in the options provided.

let options: ActionOptions = {
    title: "Sticky Dialog",
    message: "Will not disappear if background tapped",
    cancelable: false,
    actions: ["Cancel", "OK"]
};

dialogs.action(options).then(result => {
   console.log(result);
});

But when showing my custom modal using the ModalDialogService there is no such property that can be set in the options, currently I have

let modalOptions: ModalDialogOptions = {
    context: {},
    fullscreen: false,
    viewContainerRef: this.vcRef,
};

this.modalService.showModal(DeviceRegistrationComponent, modalOptions)
     .then(result => {
         if (result != null) {
            this.handleDeviceOtpEntry(result.otp);
         }
     });

Is there a way to accomplish this? I do not mind having to set the specific native android properties, but cannot seem to be able to get a handle to the actual modal that gets displayed.


Solution

  • Ok, so after some trial and error managed to come up with a solution (if there is a better way please let me know)

    It seems from looking at the source that if we create a modal dialog using the ModalDialogService there is no convenient way to set cancelable for android, so instead, in my modal component I listen for the shownModally event and once fired, we can then attempt to find the currently displayed fragment, which is created by NativeScript with the tag dialog.

    Once we have that we can simply set the native property.

    import {Component} from "@angular/core";
    import {Page} from "tns-core-modules/ui/page";
    import {ModalDialogParams} from "nativescript-angular";
    import * as application from "tns-core-modules/application";
    import {isAndroid} from "tns-core-modules/platform";
    
    @Component({
        moduleId: module.id,
        selector: "app-device-registration",
        templateUrl: "./device.registration.component.html",
        styleUrls: ["./device.registration.component.css"]
    })
    export class DeviceRegistrationComponent {
    
    constructor(private params: ModalDialogParams, private page: Page) {
        this.page.on("shownModally", data => {
            if (isAndroid) {
                let fragmentManger = application.android.foregroundActivity.getFragmentManager();
                let dialogFragment = fragmentManger.findFragmentByTag("dialog");
                if (dialogFragment !== null) {
                    dialogFragment.setCancelable(false);
                }
            }
    
        });
    }