Interacting with a Mobile Application
Mobile devices introduce some new interaction methods that you need to consider during the development of your application. XPages provides additional mobile events to support the following mobile specific interaction methods:
- Orientation-based
- Touch-based
- Multitouch-based
Orientation-Based Interaction
The optimum layout of the UI can vary depending on the device orientation. Your application should respond to orientation change events and adapt the UI accordingly. If this is not possible, the UI should be designed to provide a good user experience for each orientation. CSS provides functionality that allows you to control the presentation based on the media type; the @media rule can be used to optionally hide content depending on the orientation. Listing 14.12 shows some CSS that defines a style class that enables you to hide elements in portrait orientation. The @media rule is used to define different values for the style class based on the current orientation, which hides it when in portrait mode.
Listing 14.12 Landscape-Only Display
@media only screen and (orientation:portrait) { .landscape-only { display: none; } } @media only screen and (orientation:landscape) { .landscape-only { display: block; } }
Listing 14.13 shows an XPage that uses the CSS in Listing 14.12. The Application Page has a control that displays only in landscape orientation. When you run this sample and switch the device orientation, the Optional Stuff shows or hides automatically.
Listing 14.13 Landscape-Only Display Using CSS
<?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"> <xp:this.resources> <xp:styleSheet href="/orientation.css"></xp:styleSheet> </xp:this.resources> <xe:singlePageApp selectedPageName="orientationPage"> <xe:appPage id="orientationPage" pageName="orientationPage"> <xe:djxmHeading id="djxmHeading3"> <xe:this.label>Orientation</xe:this.label> </xe:djxmHeading> <xe:djxmRoundRectList id="djxmRoundRectList1"> Required Stuff </xe:djxmRoundRectList> <xe:djxmRoundRectList id="djxmRoundRectList2" styleClass="landscape-only"> Optional Stuff </xe:djxmRoundRectList> </xe:appPage> </xe:singlePageApp> </xp:view>
Listing 14.14 shows a further refinement on this technique to define separate style sheets for each orientation and then uses the media attribute on the xp:styleSheet tag to determine which style sheet is used.
Listing 14.14 Landscape-Only Display Using Style Sheets
<?xml version="1.0" encoding="UTF-8"?> <?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"> <xp:this.resources> <xp:styleSheet media="only screen and (orientation:portrait)" href="/portrait.css"></xp:styleSheet> <xp:styleSheet media="only screen and (orientation:landscape)" href="/lanscape.css"></xp:styleSheet> </xp:this.resources> <xe:singlePageApp selectedPageName="orientationPage"> <xe:appPage id="orientationPage" pageName="orientationPage"> <xe:djxmHeading id="djxmHeading3"> <xe:this.label>Orientation</xe:this.label> </xe:djxmHeading> <xe:djxmRoundRectList id="djxmRoundRectList1"> Required Stuff </xe:djxmRoundRectList> <xe:djxmRoundRectList id="djxmRoundRectList2" styleClass="landscape-only"> Optional Stuff </xe:djxmRoundRectList> </xe:appPage> </xe:singlePageApp> </xp:view>
Starting with the 9.0.1 release XPages now includes an onOrientationChange event on the Single Page Application control. You can write client-side application logic, which is executed when the user changes the device orientation. Listing 14.15 shows some client-side JavaScript, which is called in response to an orientation change. The orientation property can have the following values:
- 0: Portrait mode
- 90: Landscape mode with the screen turned to the left
- -90: Landscape mode with the screen turned to the right
- 180: Portrait mode with the screen upside down
Not all devices support all the modes, for example, iOS devices do not support 180. Also notice in this sample that the initial value is set to Unknown. It is not possible to write a server-side computed expression that computes the current orientation. Because of network latency, the user could have changed the device orientation between requesting the page and it displaying. Therefore, client-side computations need to be used when developing orientation-based logic.
Listing 14.15 onOrientation Change Event
<?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="orientationChangePage" id="singlePageApp1"> <xe:appPage id="orientationChangePage" pageName="orientationChangePage"> <xe:djxmHeading id="djxmHeading3"> <xe:this.label>OnOrientationChange</xe:this.label> </xe:djxmHeading> <xp:label value="Unknown" id="label1"></xp:label> </xe:appPage> <xp:eventHandler event="onOrientationChange" submit="false"> <xe:this.script> <![CDATA[ var label = document.getElementById("view:_id1:orientationChangePage_ content:label1"); if ( orientation == 0 ) { label.innerHTML = "Portrait Mode {orientation=0}"; } else if ( orientation == 90 ) { label.innerHTML = "Landscape Mode {orientation=90}"; } else if ( orientation == -90 ) { label.innerHTML = "Landscape Mode {orientation=-90}"; } else if ( orientation == 180 ) { label.innerHTML = "Portrait Mode {orientation=180}"; } ]]> </xe:this.script> </xp:eventHandler> </xe:singlePageApp> </xp:view>
Touch-Based Interaction
Most mobile devices now support the ability for users to interact using a finger or stylus. When designing a UI for a touch-based interaction, controls should be positioned and sized so users can individually select them. Controls that can be selected need to be large enough so that they can be easily selected and it is clear which item is currently selected. Remember part of the screen may be obscured by users’ fingers as they select items, so you need to make sure that you provide feedback (for example, use roll-overs) to indicate what item is currently selected. Also, you need to avoid frustrating users if they cannot easily select a particular option. Listing 14.16 shows an example of interacting with touch-based events when using the mobile switch.
Listing 14.16 onTouchStart and onTouchEnd Events
<?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="transitionPage"> <xe:appPage id="transitionPage" pageName="transitionPage"> <xe:djxmHeading id="djxmHeading3"> <xe:this.label>Transition</xe:this.label> </xe:djxmHeading> <xp:label value="Swipe Me: " id="label1"></xp:label> <xe:djxmSwitch leftLabel="ON" rightLabel="OFF" id="djxmSwitch1"> <xp:eventHandler event="onTouchStart" submit="false"> <xe:this.script> <![CDATA[ var label1Id = '#{javascript:getClientId("label1")}'; var label1 = document.getElementById(label1Id); label1.innerHTML = "--- Swiping ---"; ]]> </xe:this.script> </xp:eventHandler> <xp:eventHandler event="onTouchEnd" submit="false"> <xe:this.script> <![CDATA[ var label1Id = '#{javascript:getClientId("label1")}'; var label1 = document.getElementById(label1Id); label1.innerHTML = "Swiped Me: "; ]]> </xe:this.script> </xp:eventHandler> </xe:djxmSwitch> </xe:appPage> </xe:singlePageApp> </xp:view>
Multitouch-Based Interaction
A multitouch interaction is the ability of the touch screen to detect the presence of multiple points of contact. One of the most common multitouch gestures is pinch-to-zoom, which allows the user to zoom in and out. When designing an XPage that will be accessed on a mobile device, you must take care to ensure users don’t need to zoom when they first view the page. You may have some XPages that you don’t want to or have time to convert to a mobile design, but you can still improve the experience for mobile users by making sure the pages render with the optimum zoom when accessed with a mobile device. The way you do this is to use the viewport meta tag. Listing 14.17 shows how to set the viewport for an XPage using the xp:metaData tag with a width of 500. (A further enhancement would be to compute this value based on the specific device.)
Listing 14.17 Viewport Meta Tag
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core"> <xp:this.resources> <xp:metaData name="viewport" content="width=500"> </xp:metaData> </xp:this.resources> <h1>Mobile XPages Applications</h1> ... </xp:view>
Take, for example, the launch page (index.xsp) for this chapter’s sample database. Figure 14.11 shows how the page will display first with the default viewport width (which is 980 for an iPhone) and then with the viewport set as shown in Listing 14.17. The XPage is displayed in a more readable and usable manner by changing the width.
Figure 14.11 With and without viewport
The viewport meta tag supports some other attributes that allow you to control how your XPages displays:
- width: Viewport width, that is, the width of the page a user sees.
- height: Viewport height, that is, the height of the page a user sees.
- initial-scale: Initial zoom scale of the viewport.
- maximum-scale: Maximum view scale of the view port.
- minimum-scale: Minimum view scale of the view port.
- user-scalable: Determines if the user is allowed to zoom in and out of the viewport.