NativeScript Core

Modal View

Use the showModal method of the View class to show another view as a modal dialog. You must specify the location of the modal page module. You can provide a context and a callback function that will be called when the modal view is closed. You can also optionally specify whether to show the modal view in fullscreen or not. To close the modal view, you need to subscribe to its shownModally event and store a reference to a close callback function provided by the event arguments. Call this function when you are ready to close the modal view, optionally passing some results to the master page. Here is an example with two views — the main view and a login view. The main one shows the login view modally; the user enters their username and password and when ready clicks the Login button. This closes the modal login view and returns the username/password to the main page which can then log the user in.

TIP: By design on iPhone, a modal view appears only in fullscreen.

Basics

Main view

<Page xmlns="http://www.nativescript.org/tns.xsd">
    <Page.actionBar>
        <ActionBar title="Getting Started"/>
    </Page.actionBar>

    <GridLayout rows="auto, *">

        <Button text="Open modal" tap="openModal" textWrap="true" />

    </GridLayout>
</Page>
const modalViewModule = "ns-ui-category/modal-view/basics/modal-view-page";

function openModal(args) {
    const mainView = args.object;
    const option = {
        context: { username: "test_username", password: "test" },
        closeCallback: (username, password) => {
            // Receive data from the modal view. e.g. username & password
            alert(`Username: ${username} : Password: ${password}`);
        },
        fullscreen: true
    };
    mainView.showModal(modalViewModule, option);

}
exports.openModal = openModal;
import { Button } from "tns-core-modules/ui/button";
import { ShowModalOptions } from "tns-core-modules/ui/core/view";
const modalViewModulets = "ns-ui-category/modal-view/basics/modal-ts-view-page";

export function openModal(args) {
    const mainView: Button = <Button>args.object;
    const option: ShowModalOptions = {
        context: { username: "test_username", password: "test" },
        closeCallback: (username, password) => {
            // Receive data from the modal view. e.g. username & password
            alert(`Username: ${username} : Password: ${password}`);
        },
        fullscreen: true
    };
    mainView.showModal(modalViewModulets, option);
}

Modal view

<Page xmlns="http://www.nativescript.org/tns.xsd" shownModally="onShownModally">
    <StackLayout>
        <GridLayout rows="100 100" columns="* 2*">
            <Label row="0" col="0" text="Username:" textWrap="true" />
            <TextField row="0" col="1" hint="username" text="{{ username }}" />
            <Label row="1" col="0" text="Password:" textWrap="true" />
            <TextField row="1" col="1" hint="password" secure="true" text="{{ password }}" />
        </GridLayout>
        <Button text="SingIn" tap="onLoginButtonTap" />
    </StackLayout>
</Page>
const observableModule = require("tns-core-modules/data/observable");
let closeCallback;

function onShownModally(args) {
    const context = args.context;
    closeCallback = args.closeCallback;
    const page = args.object;
    page.bindingContext = observableModule.fromObject(context);
}
exports.onShownModally = onShownModally;

function onLoginButtonTap(args) {
    const page = args.object.page;
    const bindingContext = page.bindingContext;
    const username = bindingContext.get("username");
    const password = bindingContext.get("password");
    closeCallback(username, password);
}
exports.onLoginButtonTap = onLoginButtonTap;
import { fromObject } from "tns-core-modules/data/observable";
import { Page } from "tns-core-modules/ui/page";
let closeCallback;

export function onShownModally(args) {
    const context = args.context;
    closeCallback = args.closeCallback;
    const page: Page = <Page>args.object;
    page.bindingContext = fromObject(context);
}

export function onLoginButtonTap(args) {
    const page: Page = <Page>args.object.page;
    const bindingContext = page.bindingContext;
    const username = bindingContext.get("username");
    const password = bindingContext.get("password");
    closeCallback(username, password);
}

Note: With version 4.0.0 of NativeScript, opening a Modal view from another Modal view is officially supported. The previous versions of NativeScript supported only a single Modal view.

Improve this document

Demo Source


Custom Actionbar

With NativeScript version 4.0.0, we can also show custom ActionBar in the modal view. To do that, we should declare a root frame and to set up our default modal view.

Main page

<Page xmlns="http://www.nativescript.org/tns.xsd">
    <Page.actionBar>
        <ActionBar title="Modal view Navigation"/>
    </Page.actionBar>

    <GridLayout rows="auto, *">

        <Button text="Open modal" tap="openModal" textWrap="true" />

    </GridLayout>
</Page>
const modalView = "ns-ui-category/modal-view/custom-actionbar/modal-root";

function openModal(args) {
    const mainpage = args.object.page;
    const option = {
        context: "some context",
        closeCallback: () => {},
        fullscreen: true
    };
    mainpage.showModal(modalView, option);
}
exports.openModal = openModal;
import { Page } from "tns-core-modules/ui/page";
import { ShowModalOptions } from "tns-core-modules/ui/core/view";
const modalView = "ns-ui-category/modal-view/custom-actionbar/modal-ts-root";

export function openModal(args) {
    const mainpage: Page = <Page>args.object.page;
    const option: ShowModalOptions = {
        context: "some context",
        closeCallback: () => {},
        fullscreen: true
    };
    mainpage.showModal(modalView, option);
}

Modal root

<Frame defaultPage="ns-ui-category/modal-view/custom-actionbar/modal-view-page"/>
<Frame defaultPage="ns-ui-category/modal-view/custom-actionbar/modal-ts-view-page"/>

Modal view

<Page backgroundColor="green" showingModally="onShowingModally">
    <Page.actionBar>
        <ActionBar backgroundColor="red" title="Modal view" icon="">
        </ActionBar>
    </Page.actionBar>
    <StackLayout backgroundColor="lightGreen">
        <Label text="Modal view with ActionBar" style="text-align:center;" textWrap="true" />
        <Button text="Close Modal" tap="onCloseModal"/>
    </StackLayout>
</Page>
function onShowingModally(args) {
    console.log("onShowingModally");
}
exports.onShowingModally = onShowingModally;

function onCloseModal(args) {
    args.object.closeModal();
}
exports.onCloseModal = onCloseModal;
export function onShowingModally(args) {
    console.log("onShowingModally");
}

export function onCloseModal(args) {
    args.object.closeModal();
}

Improve this document

Demo Source


With NativeScript version 4.0.0 and above, we can navigate within a modal view. We need a root frame defaulting to our first modal view. With the Frame instance, we can navigate within the modal and with the help of closeModal method, we can close the modal from any View instance.

Main page

<Page xmlns="http://www.nativescript.org/tns.xsd">
    <Page.actionBar>
        <ActionBar title="Modal view Navigation"/>
    </Page.actionBar>

    <GridLayout rows="auto, *">

        <Button text="Open modal" tap="openModal" textWrap="true" />

    </GridLayout>
</Page>
const modalView = "ns-ui-category/modal-view/modal-navigation/modal-root";

function openModal(args) {
    const mainpage = args.object.page;
    const options = {
        context: "some context",
        closeCallback: () => {
        },
        fullscreen: true
    };
    mainpage.showModal(modalView, options);
}
exports.openModal = openModal;
import { ShowModalOptions } from "tns-core-modules/ui/core/view";
const modalView = "ns-ui-category/modal-view/modal-navigation/modal-root";

function openModal(args) {
    const mainpage = args.object.page;
    const options: ShowModalOptions = {
        context: "some context",
        closeCallback: () => {},
        fullscreen: true
    };
    mainpage.showModal(modalView, options);
}
exports.openModal = openModal;

Modal root

<Frame defaultPage="ns-ui-category/modal-view/modal-navigation/first-modal-view-page"
       shownModally="onShownModally" 
       showingModally="onShowingModally"/>
<Frame defaultPage="ns-ui-category/modal-view/modal-navigation/first-modal-ts-view-page" 
       shownModally="onShownModally" 
       showingModally="onShowingModally"/>

First modal view

<Page backgroundColor="green" loaded="onPageLoaded">
    <StackLayout backgroundColor="lightGreen">
        <Button text="Navigate" tap="onNavigate"/>
        <Button text="Close Modal" tap="onCloseModal"/>
    </StackLayout>
</Page>
function onNavigate(args) {
    const view = args.object;
    const page = view.page;
    page.frame.navigate("ns-ui-category/modal-view/modal-navigation/second-modal-view-page");
}
exports.onNavigate = onNavigate;

function onPageLoaded(args) {
    console.log("onPageLoaded");
}
exports.onPageLoaded = onPageLoaded;

function onCloseModal(args) {
    args.object.closeModal();
}
exports.onCloseModal = onCloseModal;
import { Page } from "tns-core-modules/ui/page";
export function onNavigate(args) {
    const view = args.object;
    const page: Page = <Page>view.page;
    page.frame.navigate("ns-ui-category/modal-view/modal-navigation/second-modal-ts-view-page");
}

export function onPageLoaded(args) {
    console.log("onPageLoaded");
}

export function onCloseModal(args) {
    args.object.closeModal();
}

Second modal view

<Page class="page">
    <StackLayout>
        <Label style="text-align:center;"  text="Second view"/>
        <Button text="Navigate Back" tap="onGoBack"/>
        <Button text="Close Modal" tap="onCloseModal"/>
    </StackLayout>
</Page>
function onGoBack(args) {
    const view = args.object;
    const page = view.page;

    page.frame.goBack();
}
exports.onGoBack = onGoBack;

function onCloseModal(args) {
    args.object.closeModal();
}
exports.onCloseModal = onCloseModal;
import { Page } from "tns-core-modules/ui/page";

export function onGoBack(args) {
    const view = args.object;
    const page: Page = <Page>view.page;

    page.frame.goBack();
}

export function onCloseModal(args) {
    args.object.closeModal();
}

Improve this document

Demo Source