Mobile Application Navigation
Users should always know where they are within your application and how to get back to where they have just come from. The views in your application can be organized in different ways. For example, you could implement a navigator that allows the user to jump straight to a particular place in the application. This is best-suited where the application views are organized in a simple flat list. In a mobile application you may not have the luxury of displaying the navigator all the time, so the ability to quickly get back to the main navigator is important. Another common approach is to use a menu-like hierarchical navigation scheme in which users select different options to navigate through the hierarchy. When using a hierarchical scheme, a Back button is important to allow users to quickly retrace their steps. The final approach you look at is providing context-sensitive navigation options. In this case, users will be provided with the navigation options that logically make sense based on where they are and what they are doing within the application.
You saw an example of how to do navigation using the Rounded List Item (xe:djxmLineItem) control earlier in this chapter in Listing 14.4. The Rounded List Item control enables you to specify the page name to move to but also the transition type to use. The valid types of transition are
- slide:New pages moves in from the side to cover the old page. This is the default.
- fade:The old page fades out while the new page fades in.
- flip:The old page flips over to display the new page as if the new page were printed on the back of the old page.
- none:The new page appears immediately without any transition effect.
Listing 14.5 shows how to specify the transition type that will be used when a user changes the Application Page.
Listing 14.5 Application Page Transitions
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex" xmlns:xc="http://www.ibm.com/xsp/custom"> <xe:singlePageApp id="singlePageApp1" selectedPageName="appPage1"> <xe:appPage id="appPage1" pageName="appPage1"> <xe:djxmHeading id="djxmHeading1"> <xe:this.label>Page 1</xe:this.label> </xe:djxmHeading> <xe:djxmLineItem id="djxmLineItem1" label="Fade to Page 2" moveTo="appPage2" transition="fade"> </xe:djxmLineItem> </xe:appPage> <xe:appPage id="appPage2" pageName="appPage2"> <xe:djxmHeading id="djxmHeading2"> <xe:this.label>Page 2</xe:this.label> </xe:djxmHeading> <xe:djxmLineItem id="djxmLineItem2" label="Flip to Page 1" moveTo="appPage1" transition="flip"> </xe:djxmLineItem> </xe:appPage> </xe:singlePageApp> </xp:view>
Navigator
To implement a basic navigator, you need to use the Page Heading (xe:djxmHeading) and Rounded List Item (xe:djxmLineItem) controls. Listing 14.6 shows an XPage that provides a basic navigator. The Page Heading shows users where they are within the application at all times. Each Page Heading includes two additional attributes:
- back: Label for the back button
- moveTo: Page to move to when the Back button is selected
The combination of these two parameters adds a Back button to each page, which allows users to return to the Home page, which includes the Navigator with a single-click. The main Navigator displays on its own Application Page to optimize real estate on the device.
Listing 14.6 Navigator XPage
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex" xmlns:xc="http://www.ibm.com/xsp/custom"> <xe:singlePageApp id="navigationApp" selectedPageName="homePage"> <xe:appPage id="homePage" pageName="homePage"> <xe:djxmHeading id="djxmHeading1"> <xe:this.label>Home</xe:this.label> </xe:djxmHeading> <xe:djxmLineItem label="Visitor Info" moveTo="visitorPage"/> <xe:djxmLineItem label="Conservation" moveTo="conservePage"/> <xe:djxmLineItem label="Education" moveTo="educatePage"/> <xe:djxmLineItem label="Get Involved" moveTo="involvePage"/> <xe:djxmLineItem label="Shop" moveTo="shopPage"/> </xe:appPage> <xe:appPage id="visitorPage" pageName="visitorPage"> <xe:djxmHeading back="Home" moveTo="homePage"> <xe:this.label>Visitor Info</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="conservePage" pageName="conservePage"> <xe:djxmHeading back="Home" moveTo="homePage"> <xe:this.label>Conservation</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="educatePage" pageName="educatePage"> <xe:djxmHeading back="Home" moveTo="homePage"> <xe:this.label>Education</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="involvePage" pageName="involvePage"> <xe:djxmHeading back="Home" moveTo="homePage"> <xe:this.label>Get Involved</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="shopPage" pageName="shopPage"> <xe:djxmHeading back="Home" moveTo="homePage"> <xe:this.label>Shop</xe:this.label> </xe:djxmHeading> </xe:appPage> </xe:singlePageApp> </xp:view>
Figures 14.8 and 14.9 show the Home page with the XPages Navigator and also an Application Page, which includes a Page Heading with an integrated Back button to return to the Home page.
Figure 14.8 Mobile Navigator
Figure 14.9 Page Heading with Back button
Hierarchical Navigation
Hierarchical navigation can be implemented with the Outline (xe:outline) and associated Node (xe:basicContainerNode and xe:basicLeafNode) controls. Listing 14.7 shows a custom control that supports hierarchical navigation for a Single Page Application. The Outline has a collection of Container Nodes, which in turn have a collection of children that are Basic Nodes and represents the leaves in the tree structure. Selecting one of the Basic Nodes will trigger navigation to the associated Application Page within the Single Page Application.
Listing 14.7 Outline Custom Control
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex"> <xe:outline id="outline1"> <xe:this.treeNodes> <xe:basicContainerNode label="Services"> <xe:this.children> <xe:basicLeafNode label="Business" href="#businessPage"> </xe:basicLeafNode> <xe:basicLeafNode label="Training" href="#trainingPage"> </xe:basicLeafNode> </xe:this.children> </xe:basicContainerNode> <xe:basicContainerNode label="Products"> <xe:this.children> <xe:basicLeafNode label="Software" href="#softwarePage"> </xe:basicLeafNode> <xe:basicLeafNode label="Systems" href="#systemsPage"> </xe:basicLeafNode> </xe:this.children> </xe:basicContainerNode> <xe:basicContainerNode label="Support"> <xe:this.children> <xe:basicLeafNode label="Downloads" href="#downloadsPage"> </xe:basicLeafNode> </xe:this.children> </xe:basicContainerNode> </xe:this.treeNodes> </xe:outline> </xp:view>
Listing 14.8 shows the Single Page Application that uses the Outline custom control.
Listing 14.8 Hierarchical Navigation XPage
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex" xmlns:xc="http://www.ibm.com/xsp/custom"> <xe:singlePageApp id="navigationApp" selectedPageName="outlinePage"> <xe:appPage id="outlinePage" pageName="outlinePage"> <xc:Outline></xc:Outline> </xe:appPage> <xe:appPage id="businessPage" pageName="businessPage"> <xe:djxmHeading back="Services" moveTo="outlinePage"> <xe:this.label>Business</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="trainingPage" pageName="trainingPage"> <xe:djxmHeading back="Services" moveTo="outlinePage"> <xe:this.label>Training</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="softwarePage" pageName="softwarePage"> <xe:djxmHeading back="Products" moveTo="outlinePage"> <xe:this.label>Software</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="systemsPage" pageName="systemsPage"> <xe:djxmHeading back="Products" moveTo="outlinePage"> <xe:this.label>Systems</xe:this.label> </xe:djxmHeading> </xe:appPage> <xe:appPage id="downloadsPage" pageName="#downloadsPage"> <xe:djxmHeading back="Support" moveTo="outlinePage"> <xe:this.label>Downloads</xe:this.label> </xe:djxmHeading> </xe:appPage> </xe:singlePageApp> </xp:view>
Context-Sensitive Navigation
Context-sensitive navigation means that your application provides users with the navigation options that represent the next logical steps within the application. It is important not to overload users with too many navigation options because this can make your application difficult to use, and mobile application users have a very low tolerance for difficult-to-use applications.
Listing 14.9 shows a mobile XPage with four application pages used for home, start, settings, and advanced functionality. In this scenario, the advanced functionality is only accessible from the Settings page. The intention here is to hide complexity, but another reason to do this is that it might only make sense to make screens available after another operation—for example, after the start functionality.
Listing 14.9 Context-Sensitive Navigation XPage
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex" xmlns:xc="http://www.ibm.com/xsp/custom"> <xe:singlePageApp id="contextSensitiveApp" selectedPageName="homePage"> <xe:appPage id="homePage" pageName="homePage"> <xc:TabBar pageName="home"></xc:TabBar> Home Page </xe:appPage> <xe:appPage id="startPage" pageName="startPage"> <xc:TabBar pageName="start"></xc:TabBar> Start Page </xe:appPage> <xe:appPage id="settingsPage" pageName="settingsPage"> <xc:TabBar pageName="settings"></xc:TabBar> Settings Page </xe:appPage> <xe:appPage id="advancedPage" pageName="advancedPage"> <xc:TabBar pageName="advanced"></xc:TabBar> Advanced Page </xe:appPage> </xe:singlePageApp> </xp:view>
The navigation for this application is implemented in the page heading using a segmented button list, as shown in Figure 14.10.
Figure 14.10 Heading with segmented buttons
The functionality is encapsulated in a custom control, the code for which is demonstrated in Listing 14.10. A Page Heading with a nested Tab Bar is used to implement this navigation strategy. The custom control takes a single parameter that is the name of the page currently displayed. Each Tab Bar button uses a computed rendered property to determine if it should display. The button for the advanced screen displays only when the Settings screen is active.
Listing 14.10 Context-Sensitive Navigation Custom Control
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex"> <xe:djxmHeading> <xe:tabBar id="tabBar1" style="background-color:rgb(255,255,255);width:100%;" barType="segmentedControl"> <xe:tabBarButton id="homeButton" label="Home" rendered="#{javascript:compositeData.pageName!='home'}" onClick="location.hash='#homePage';"> </xe:tabBarButton> <xe:tabBarButton id="startButton" label="Start" onClick="location.hash='#startPage';"> <xe:this.rendered> <![CDATA[#{javascript:compositeData.pageName!='start' && compositeData.pageName!='advanced'}]]> </xe:this.rendered> </xe:tabBarButton> <xe:tabBarButton id="settingsButton" label="Settings" rendered="#{javascript:compositeData.pageName!='settings'}" onClick="location.hash='#settingsPage';"> </xe:tabBarButton> <xe:tabBarButton id="advancedButton" label="Advanced" onClick="location.hash='#advancedPage';"> <xe:this.rendered> <![CDATA[#{javascript:compositeData.pageName!='home' && compositeData.pageName!='start' && compositeData.pageName!='advanced'}]]> </xe:this.rendered> </xe:tabBarButton> </xe:tabBar> </xe:djxmHeading> </xp:view>
Another commonly used way to implement this pattern is to use a Tab Bar with a list of icons for navigation displayed at the bottom of the screen.
Now you have seen how to navigate around your application using a number of commonly used patterns. There may be times in which you need to write script that responds to transition events—for example, to prompt the user to perform some action with values entered on the current page. Starting in the 9.0.1 release, XPages also supports new touch-based events:
- onBeforeTransitionIn: Triggered before transitioning into a page
- onAfterTransitionIn: Triggered after transitioning into a page
- onBeforeTransitionOut: Triggered before transitioning out of a page
- onAfterTransitionOut: Triggered after transitioning out of a page
The XPage in Listing 14.11 shows how to block transition out of a page.
Listing 14.11 onBeforeTransitionOut Sample XPage
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex"> <xe:singlePageApp selectedPageName="firstPage"> <xe:appPage id="transitionPage" pageName="firstPage"> <xp:eventHandler event="onBeforeTransitionOut" submit="false"> <xe:this.script> <![CDATA[ alert("Leaving First page!"); ]]> </xe:this.script> </xp:eventHandler> <xe:djxmHeading id="djxmHeading3"> <xe:this.label>First</xe:this.label> </xe:djxmHeading> <xe:djxmLineItem label="Second Page" moveTo="secondPage"/> </xe:appPage> <xe:appPage id="secondPage" pageName="secondPage"> <xe:djxmHeading id="djxmHeading1"> <xe:this.label>Second</xe:this.label> </xe:djxmHeading> <xe:djxmLineItem label="First Page" moveTo="firstPage"/> </xe:appPage> </xe:singlePageApp> </xp:view>