In Part One I talked in generic terms about the differing approaches when developing for mobile browsers compared to desktop browsers. Screen sizes make dialog boxes for pickers less desirable than in desktop browsers. Connectivity concerns mean typeahead and partial refresh functionality could perform worse on mobile devices and impact the user experience. Smaller resolutions can also make it harder to select from a standard Edit Box with typeahead enabled or ComboBox.

In this part I will demonstrate a predominantly client-side approach, picking options from a view. But the same technique could equally be used to select from a static list of options or options retrieved from a keyword document or Server-Side JavaScript / Java function. The database I’ll be using is the XPages Extension Library Demo database, creating a mobile interface to create a simple contact. The picker will select states.

The first step is to create an additional view in the database, because the AllStates view is not sorted. I’ve just created a copy of the view, switched the columns round, and sorted the Name column, as below:

Copy of AllStates View

So now onto the Mobile Page. The code for the XPage is attached at the bottom of this post. A dominoDocument datasource is bound to the XPage and uses the Contact form, with action=”newDocument”.

The Single Page Application mobile control is added – the container for the mobile pages, with the selectedPageName set to “welcome”. The first Mobile Page control is added with the pageName “welcome”. This has a Page Heading control and a Static Line Item which will move to the “user” page. This will be the page for creating a new user. What we have so far is below:

Mobile Page Part One

Another Single Page control is added. The key is ensuring resetContent is still set to “false” – we don’t want to reload the content every time we go to the page. Otherwise, we’ll lose all previously entered values. But this has other implications, as we will see later. Next a Single Page Heading and Form Table control are added. The details for most are not important. The focus at this point is on formRow4. The Edit Box with id inputText3 has disabled set to “true”, so the user cannot type into the field but a value can be written to it via Client-Side JavaScript and stored via the value binding to document1.State. This is standard functionality that might equally be seen in an XPage designed for desktop browsers.

Alongside the Edit Box, a Button is added. When designing for desktop browsers this would launch the Value Picker, but here it just runs Client-Side JavaScript to set location.href=”#stateSelector”. If you’ve used the Mobile Controls much (or the Dynamic Content controls – the concept is the same for both), you will have noticed that anchor tags (the #) are used to navigate between areas of the page. So setting location.href=”#stateSelector” is the same as setting moveTo on a Page Heading or Static Line Item control, and moves to the stateSelector Mobile Page. formRow4 looks like this:Mobile Page formRow4

For the moment, skip directly to the stateSelector Mobile Page, which is the interface to allow the user to select states. In normal XPages desktop browser interface, this is what would be the Value Picker. The Mobile Page contains a Page Heading, with the Back button given the label “Cancel” and moveTo value set to “user”. A Rounded List is then added, just to provide a nice mobile-styled container.

Typeahead filtering is provided via the search1 Edit Box. The value is bound to a viewScope variable called “search” and an onkeyup event applied to partially refresh the element “refreshPanel”. This typeahead filtering is only added because the user is selecting from a view with a large number of options. If the options are limited, this wouldn’t be required and should be avoided in order to further minimise calls to the server. This particular implementation adds no styling to the Edit Box. If you want to make it look nicer, look at the mobileSearch Custom Control in the Discussion XL template that comes with the Extension Library for 8.5.3.

Below the Edit Box the refreshPanel Panel control is added. A dominoView datasource is bound to this Panel, using the “Copy of AllStates” view. The keys property is set as “#{}”, to use what the user enters into the search1 Edit Box, and keysExactMatch is set to “false” so it only does a partial match. Again, if picking from a smaller list, this filtering will not be required. If picking from a Keyword document, ViewEntryCollection, Java bean or some other element, the filtering will need to be handled differently. That is generic XPages functionality and not mobile-specific, so out of the scope for this series.

The options for the user to select from are held in a Repeat Control bound to the dominoView datasource with the variable name “state”. In this example only 10 rows are shown, no pagers are provided, because the typeahead should be used to filter. Again, I’m not going to go into details on what to do if you need other functionality.

The contents of the Repeat Control are slightly unusual, so I will elaborate. What we want to do is capture the value of the row clicked, move pack to the user Mobile Page, and pass the value back to the inputText3 Edit Box that is bound to document1.State. If resetContent were set to “true” on that mobile page, we could pass the value into the query string and retrieve it. But if we were to set resetContent on the user Mobile Page to “true”, the page would get reloaded every time the user redirected to it, and so previously entered values would be lost. The initial thought may be to compute the resetContent property on the user page, for example, based also on a query string parameter. But like Server-Side JavaScript in a Client-Side JavaScript Script Block, the setting used when the page is shown is the result of the computation the previous time the page was rendered. So the query string parameter would not take effect when the user switches to the page, but instead, the next time the user switches to the page.

So we need to run code to switch the page and on the completion of that, set the field. We can do all that in Client-Side JavaScript. Within the Repeat Control there is a Div using the styleClass “mblListItem”. This simulates the Static Line Item control. Within the Div is a Label control whose value is “#{state.Name}” – the Name column from the view. The Label has an onclick eventHandler with submit=”false”. First, as with the Select State button, we set location.href=”#user” to move back to the user Mobile Page. Next we call dojo.byId(“#{id:inputText3}”.value=”#{javascript:state.getColumnValue(‘Key’)}”. This gets the inputText3 Edit Box via Client-Side JavaScript and write to it the value from the Key column for the relevant row. Note that using Expression Language (“#{state.Key}”) in the eventHandler will cause the Mobile Page to fail. Adding the eventHandler to the div does not work here.

Mobile Page Value Picker

Finally, back on the user Mobile Page there is the Save button. We need to save the document and return to the welcome Mobile Page, clearing the saved dominoDocument from memory. Fortunately there is a Server-Side JavaScript Simple Action to enable this: the Move To Application Page Simple Action. This has a number of parameters that can be set. Setting saveDocument to “true” easily allows us to save the main document datasource. Setting forceFullRefresh to “true” will allow us to do a full page refresh, clearing the saved dominoDocument from memory. The targetPage parameter is the page to move to and we set the transitionType to “slide”.

Mobile Page Submit

We now have a home page, an editable form, and a page where the user can select the state. All of this has a look and feel that’s consistent with mobile, maximises the screen real estate, and does as much as possible client side. The full code for the XPage is below.

In part three, I’ll show similar functionality using more server-side functionality. Although not my preferred option, there may be information useful for some developers.

Mobile New User CSJS XPage

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.