MyMobileWeb logo

Tutorial

MyMobileWeb Version 4

20 July 2010

Authors:
José Manuel Cantera Fonseca, Telefónica I+D, jmcf@tid.es
Cristian Rodríguez de la Cruz, Telefónica I+D, crdlc@tid.es
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License


Summary

This tutorial is intended to give an overview of the development of applications using the MyMobileWeb v4.0 framework.

Status of this document

This is a draft. Comments are very welcome, please send them to mymobileweb-develop. Thank you.

Table of Contents

1. Introduction
2. Development Steps
3. Requirements
4. Information Architecture
5. Setting up the Development Environment
6. Designing the Application Flow
6.1. Using SCXML as an specification language
7. Developing the presentation layer and the application logic
7.1. Part I - Navigation Lists
7.2. Part II - Tables
7.3. Part III - Advanced Layouts (Placard)
7.4. Part IV - Carousel of Images
7.5. Part V - Statistical Graphics
7.6. Part VI - Forms
8. Maps Tutorial
8.1. Introduction
8.2. Showing placemarks
8.3. Displaying photooverlays
8.4. Tracing routes
8.5. Input locations
9. Media Tutorial
9.1. Introduction
9.2. Different representations of the same media
9.3. Using dynamic sources

1.  Introduction

<< backtop next >>

In this tutorial we will show some of the most important functionalities provided by MyMobileWeb and how developers get access to such functionalities. We will demonstrate this by developing a (minimalistic) multi-device mobile web portal dedicated to the Spanish National Soccer League ("La Liga").

2. Development Steps

<< backtop next >>

As usual, the first step to start developing your application is to gather all the requirements that need to be met. Once the requirements are known, the next activity is to design the information architecture of your portal, which will allow to determine the number of pages (presentations in MyMobileWeb jargon) needed and the navigation flow between them. Then, the structural and presentational aspects (style) of pages will be designed. The next step is to create the business logic (Application Operations in MyMobileWeb's terminology) that will give functionality and content to your application. Once you have developed the application, it has to be tested in multiple devices (or emulation environments), making the necessary adjustments and corrections. Finally, the application has to be deployed in a production environment, making it accessible to your Internet users.

3. Requirements

<< backtop next >>

The requirements for our Mobile Soccer Portal are simple and concise:

  • R1: The portal should provide the latest news about "La Liga".

  • R2: The portal should provide the latest news on a per club basics.

  • R3: The portal should provide information about the rounds, games, and standings.

  • R4: The portal should offer a functionality to navigate through club's image galleries.

  • R5: The portal must provide statistics about the competition, such as the number of Leagues won by the different clubs throughout history.

  • R6: The portal should offer a functionality for daily news subscription.

  • R7: The portal contents must be presented both in English and Spanish (internationalization requirement).

Apart from these functional requirements our application has to provide a harmonized user experience for multiple delivery contexts, especially for three "hero devices": Apple's iPhone, Windows Mobile 2005-6 enabled smartphones equipped with a IE Mobile browser and Nokia Series 40 6212 feature phones. These three devices have been chosen because they have different form factors and input mechanisms: multi-touch screen and advanced gestures, stylus or a classical four-way scroller.

4. Information Architecture

<< backtop next >>

The proposed information architecture is depicted in Figure 1. The application will have an initial menu which will give access to the different functionalities provided by the portal: the latest news of "La Liga", the information about rounds, the information dedicated to specific teams and the global statistics. The latest news about "La Liga" or about an specific team will be presented as a master-detail list. We will also dedicate a specific presentation for club image galleries. At this abstraction level, we have divided the presentation of the information about rounds in two different views: one for the games and another for the standings. The statistics will be presented in a single view which will contain a nice bar diagram.

Information Architecture

Figure 1. Information Architecture


5. Setting up the Development Environment

<< backtop next >>

Now that we have a clear view of what we want to achieve and what is the information architecture of the application, the development activities can start. First of all, it is needed to to configure the development environment. For doing so, the following products must be installed:

Then, the MyMobileWeb SDK v4 and the MyMobileWeb Eclipse plugin compatible with such a version have to be installed and configured. Both of them can be downloaded from the MyMobileWeb's web site. The application can also be developed without the Eclipse plugin, but we strongly recommend to use it as it simplifies and accelerates the development process. The following step is to create a new MyMobileWeb project using the Eclipse Plugin. This new project is already set up and configured to start the development and testing cycles of the new application.

Note

This Getting started gives you more information about how to install the development environment.

6. Designing the Application Flow

<< backtop next >>

The first step that needs to be completed in the development process is the design of the flow of the application in accordance with the information architecture previously presented. An application flow in MyMobileWeb is divided into the so called Presentation Operations (OPs). An OP represents a use case and it is composed by the set of presentations and the flow between them that realizes such a use case. Thus, we can identify the following OPs for our portal:

  • InitialMenu: This is the first OP of the application and will be called once the application is invoked by the user. This OP will contain a presentation with a menu that will allow users to choose between the different functionalities offered by our portal.

  • News: It corresponds to the use case responsible for presenting a list of news and the detail of each news presented, so at least two presentations will be needed.

  • Rounds: This OP is in charge of presenting the games and standings for the latest rounds. As the standings and games are strongly related we have decided to include both in the same presentation but in different sections.

  • Clubs: This use case is concerned with the selection and presentation of information about a team. A presentation with a menu will allow users to select the team they want to know more about.

  • Gallery: The Gallery OP is intended to present an image gallery allowing the user to select and display. Although this OP could be merged with the "Clubs" OP we have separated them for modularization and reusing purposes, as in future versions of the portal might be needed in another context.

  • Statistics: The purpose of this OP is to display statistics automatically about clubs in graphic format.

  • Tickets: This OP is in charge of presenting a form where users can buy tickets for a match.

6.1. Using SCXML as an specification language

<< backtop next >>

The next step is to specify our application flow using W3C's SCXML. Figure 2 graphically depicts the SCXML state machine corresponding to our application. In the following paragraphs we describe the SCXML formalisms and how they are mapped to the elements which intervene in an application flow: OPs, presentations, events resulting from user interaction and the application logic:

  • States: Each OP is modeled as a state that has as many substates as presentations such a OP is going to have. Following this rule, it can be seen that, for instance, the "News" OP is modeled as an state identified as "News" that has two substates: "newsList" and "newsDetail". Thus, there are two kinds of states: OP states and Presentation states. When the state machine is in a presentation state it means that the user is actually viewing and interacting with such a presentation. The framework guarantees that when a presentation state is reached the application will navigate to the corresponding page.

  • Transitions: The flow between OPs and presentations within an OP is modeled as transitions triggered by events raised by the interaction of the user with the application and (optionally) controlled by logical conditions that operate over the data model. For instance, you can see that the InitialMenu state (corresponding to the "InitialMenu" OP) has transitions to the other OPs it gives access. Such transitions are triggered when a menu option is selected and are conditioned by the value of the menu option actually selected.

  • Actions: Actions are executed when a new state is reached or when a transition is triggered. Actions can be used basically to express what application logic, Application Operations (OAs) in my MyMobileWeb terminology, should be executed. For example, when the state "newsDetail" is reached an Application Operation called "NewsOA" will be executed. Such OA will obtain from a RSS service a list with the latest news which will be displayed by the corresponding presentation. Actually, OAs are Java classes provided by the application programmer.

Apart from these transitions defined by the application programmer, MyMobileWeb adds automatically other transitions that deal with error conditions which may arise.

State Machine corresponding to the application

Figure 2. State Machine corresponding to the application


The Figure 3 depicts graphically the application flow using W3C's SCXML

<?xml version="1.0" encoding="UTF-8"?> 
<scxml xmlns="http://www.w3.org/2005/07/scxml"
	   xmlns:mymw="http://morfeo-project.org/mymobileweb" version="1.0"
	   initial="Soccer">
 
	<state id="Soccer" mymw:category="Application">
 
		<initial>
			<transition target="InitialMenu" />
		</initial>
 
		<!-- General Transitions -->
		<transition event="lback.onclick" target="InitialMenu" />
		<transition event="lindex.onclick" target="InitialMenu" />
 
		<transition event="onrequest" cond="${mymw:matches('/app/club/(.+?)')}" target="Club">
			<mymw:urlMappings>
				<mymw:bind var="sessionScope.club" />
			</mymw:urlMappings>
		</transition>
 
		<!-- Use Cases -->
		
	</state>
 
</scxml>

Figure 3. Application Flow using W3C's SCXML


Now we will decribe the flow for each use case:

  • InitialMenu: defining the flow for the first view. Go to section.

    <state id="InitialMenu" mymw:category="UseCase" initial="InitialMenu.index">
    	<state id="InitialMenu.index" mymw:category="View">
    		<transition event="init.onclick" cond="${option == 'news'}" target="News"/>
    		<transition event="init.onclick" cond="${option == 'club'}" target="Club.clubSelection"/>
    		<transition event="init.onclick" cond="${option == 'last'}" target="Club.clubDetail"/>
    		<transition event="init.onclick" cond="${option == 'rounds'}" target="Rounds"/>
    		<transition event="init.onclick" cond="${option == 'statistics'}" target="Statistics"/>
    	</state>
    </state>

    Figure 4. Initial Menu Flow


  • Rounds: defining the flow for standings and games. Go to section.

    <state id="Rounds" mymw:category="UseCase" initial="Rounds.round">
    	<state id="Rounds.round" mymw:category="View">
    		<onentry>
    			<mymw:executeOA idOA="StandingsOA"/>
    			<mymw:executeOA idOA="GamesOA"/>
    		</onentry>	
    		<transition event="next.onclick" target="Rounds.round"/>
    		<transition event="previous.onclick" target="Rounds.round"/>
    	</state>
    </state>

    Figure 5. Rounds Flow


  • News: defining the flow for news. Go to section.

    <state id="News" mymw:category="UseCase" initial="News.newsList">
    	<state id="News.newsList" mymw:category="View">
    		<onentry>
    			<if cond="${_MYMW_PREV_OP == 'InitialMenu'}">
    				<mymw:executeOA idOA="NewsListOA"/>
    			<else/>
    				<mymw:executeOA idOA="ClubNewsListOA"/>
    			</if>
    		</onentry>
    		<transition event="read.onclick" target="News.newsDetail"/>
    		<transition event="lback.onclick" cond="${_MYMW_PREV_OP == 'InitialMenu'}" target="InitialMenu"/>
    		<transition event="lback.onclick" cond="${_MYMW_PREV_OP == 'Club'}" target="Club"/>
    	</state>
    	<state id="News.newsDetail" mymw:category="View">
    		<onentry>
    			<if cond="${_MYMW_PREV_OP == 'InitialMenu'}">
    				<mymw:executeOA idOA="NewsDetailOA"/>
    			<else/>
    				<mymw:executeOA idOA="ClubNewsDetailOA"/>
    			</if>
    		</onentry>
    		<transition event="lback.onclick" target="News.newsList"/>
    	</state>
    </state>

    Figure 6. News Flow


  • Gallery: defining the flow for photo gallery. Go to section.

    <state id="Gallery" mymw:category="UseCase" initial="Gallery.gallery">
    	<state id="Gallery.gallery" mymw:category="View">
    		<onentry>
    			<mymw:executeOA idOA="GalleryOA"/>
    		</onentry>
    		<transition event="myCarousel.onclick" target="Gallery.photo"/>
    		<transition event="lback.onclick" target="Club"/>
    	</state>
    	<state id="Gallery.photo" mymw:category="View">
    		<transition event="lback.onclick" target="Gallery.gallery"/>
    	</state>
    </state>

    Figure 7. Gallery Flow


  • Statistics: defining the flow for statistics about clubs. Go to section.

    <state id="Statistics" mymw:category="UseCase" initial="Statistics.barchar">
    	<state id="Statistics.barchar" mymw:category="View">	
    		<transition event="chart.onclick" target="Club">
    			<mymw:executeOA idOA="BarCharOA"/>
    		</transition>
    	</state>
    </state>

    Figure 8. Statistics Flow


  • Tickets: defining the flow for a form of buying. Go to section.

    <state id="Tickets" mymw:category="UseCase" initial="Tickets.form">
     
    	<state id="Tickets.form" mymw:category="View"> 
    		<transition event="send.onsubmit" target="Tickets.complete" /> 
    		<transition event="lback.onclick" target="Club" /> 
    	</state>
     
    	<state id="Tickets.complete" mymw:category="View"> 
    		<transition event="ok.onsubmit" target="Club" />
     		<transition event="lmap.onclick" target="Tickets.map" />
     		<transition event="lback.onclick" target="Tickets.form" />
     	</state>
     
    	<state id="Tickets.map" mymw:category="View">
    		<onentry>
    			<mymw:executeOA idOA="MapOA" />
    		</onentry>
            <transition event="lback.onclick" target="Tickets.complete" />
        </state>
    
    </state>
    

    Figure 9. Tickets Flow


7. Developing the presentation layer and the application logic

<< backtop next >>

This section talks about the development of an application guided by MyMobileWeb's UI components.

7.1. Part I - Navigation Lists

<< backtop next >>

7.1.1. Creating the initial menu

The presentation layer in MyMobileWeb is developed using the IDEAL2 language. We will start looking into IDEAL2 using the presentation which will give access to the different functionalities provided by our portal (index). The XML corresponding to such presentation can be seen in Figure 10. There are two main blocks: the resources block in which dependencies are declared (script code, CSS sheets, etc.) and the ui section devoted to the structure of the user interface. IDEAL2 only is concerned with the specification of the presentation structure. The look-and-feel and layout is controlled by means of CSS. This approach has the advantage that the user interface can be customized for different devices without duplicating the XML code.

A presentation in IDEAL2 is structured in sections. There are two (optional) special sections, the header and the footer. If declared, these two sections will always appear at the top or the bottom of the final page regardless of pagination. As in our portal the header and the footer are always the same, they include common content to avoid duplication. A section typically contains one or more div blocks which act as second level containers. Different user interface elements can appear inside a div. In our first example, we can see a menu which contains as many options as functionalities are provided by our portal. It is important to observe that the identifier assigned to the menu options it is the same as the identifier used by the SCXML state machine.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="index" title="La liga"> 
 <resources>
  <link id="icon" rel="shortcut icon" expr="!mymw:belongsTo('iPhone')" type="image/x-icon" href="${myFavIcon}" />
  <link id="iconIPhone" rel="apple-touch-icon" expr="mymw:belongsTo('iPhone')" href="${myFavIcon}" />
  <link rel="stylesheet" id="soccerStyle" href="soccer.css" />
 </resources> 
 <ui>
  <body>
   <header id="header"> 
    <include content="Common/generic/common/header" />	 
   </header> 
   <section id="main"> 
    <div>
     <menu id="init" ref="option" class="soccer">
      <a id="news" class="decorate" longtitle="Soccer News" resourceid="news">News</a>
      <a id="club" class="decorate" longtitle="My club" resourceid="team">My club</a>
      <a id="rounds" class="decorate" longtitle="Standings and games" resourceid="table">Rounds</a>
      <a id="statistics" class="decorate" longtitle="Winners statistics" resourceid="statistics">Statistics</a>
     </menu>
    </div> 
   </section> 
   <footer id="footer"> 
    <separator class="line" />			
    <include content="Common/generic/common/powered" />	 
   </footer>
  </body>
 </ui> 
</ideal>

Figure 10. Presentation: Initial Menu


7.1.1.1. Defining the look-and-feel

To specify the look-and-feel and layout of presentations, IDEAL2 is used in conjunction with CSS. CSS sheets and styles are bound to presentations using the same syntax as in HTML. Apart from the standard CSS 2 properties, MyMobileWeb defines extended properties. Figure 11 shows the style we have assigned to our menu. It will be displayed as a vertical menu i.e. one option per line, and will have alternative background colors. It is noteworthy that MyMobileWeb provides default CSS styles (optimized for different device families) for all the user interface elements which has been proved to be extremely helpful for developers. Other elements of our page are also affected by this style sheet. For example, hyperlinks (a elements) are going to be displayed with their accompanying images. This example also demonstrates another important functionality of MyMobileWeb, which is how abstract user interface elements can be rendered in different ways using the display-as style. In this particular case the separator element is going to be realized as a horizontal rule. Other options are a line break or an image. This abstract UI rendering decision can also be made automatically by the adaptation engine (taking into account the characteristics of the device and web browser).

menu.soccer {
    layout:vertical;
    align:left;
    colored:true;
    background-color1:#ffd8ad;
    background-color2:#f7f6ef;    
    white-space:wrap;    
    width:100%;    	
}
 
a.decorate {
    img-display:both;
}
 
separator.line {    
    display-as:hr; 
}

Figure 11. CSS Styles for inital menu


7.1.1.2. Adding Images

We would like to decorate our menu with nice images. Images in a mobile environment can be problematic for two reasons: not all devices or web browsers support all image formats and the optimal image size can vary depending on the screen size available. To deal with these issues, MyMobileWeb provides two different mechanisms: selection and transcoding. Selection is a functionality that consists of choosing the best image from a set of alternatives (media set). Transcoding is the transformation of a source image provided by the developer in a target image which satisfies all the restrictions in terms of formats and optimal size. The usage of transcoding or selection depends on the availability of different sizes and formats or in the nature of the images themselves, as the transformation process may be degrading. Nonetheless, selection and transcoding are not exclusive, i.e. images can be first selected and then transcoded. In our example, it is specified an identifier (resourceid) of the media set that has to be used. The images that are part of each media set have to be left in a configurable directory in the application space.

7.1.1.3. Screenshots

Figure 12 shows how our presentation is displayed in different devices and browsers. You can see how MyMobileWeb adapts the interface and look-and-feel to be the most suitable for each device. For example, the iPhone menu is displayed in big fonts to allow a best touch selection.

Initial Menu

Figure 12. Initial Menu


7.1.2. Creating a dynamic menu

The previous example showed a presentation which structure is totally defined at design time. Now we are going to demonstrate (Figure 13) how to create a dynamic presentation which will depend on data or content calculated at runtime. In this case we also have a menu for club selection. As the number of clubs in the national league can vary depending on the season, we would like to obtain the name of the clubs from a remote service. Thus, we specify a menu as well, but instead of putting directly the options in the presentation we insert a template option with a repetition structure (repeat-nodeset attribute). This repetition structure will be controlled by a collection provided by the application logic described below. In this example, it is also shown how the attribute values can be made dynamic (using the JSP 2.0 ${x} syntax).

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="index" title="My Club"> 
 <resources>
  <link id="icon" rel="shortcut icon" expr="!mymw:belongsTo('iPhone')" type="image/x-icon" href="${myFavIcon}" />
  <link id="iconIPhone" rel="apple-touch-icon" expr="mymw:belongsTo('iPhone')" href="${myFavIcon}" />
  <link rel="stylesheet" id="soccerStyle" href="soccer.css" />
 </resources> 
 <ui>
  <body>
   <header id="header"> 
     <include content="Common/generic/common/header" /> 
   </header> 
   <section id="main"> 
    <div id="p1" class="common title.common" title="My Club">
     <menu id="myMenu" ref="club" class="clubs center">
	    <a id="header" repeat-nodeset="clubList" src="${clubList.current.image}" 
           href="${clubList.current.href}">
         ${clubList.current.name}
        </a>
     </menu>
    </div> 
   </section> 
   <footer id="footer"> 
    <include content="Common/generic/common/footer" />			
    <separator class="line" />
    <include content="Common/generic/common/powered" />	 
   </footer>
  </body>
 </ui> 
</ideal>

Figure 13. Presentation: Dynamic Menu


7.1.2.1. Creating the Application Logic

Application logic in MyMobileWeb is specified by means of the so called Application Operations (OAs). An OA is a Java class that implements a well-known interface which defines an operation to be provided by developers: execute. Such operation has an input parameter which represents the current application data model (Context class). The Context class acts as an object container. Each contained object is associated with an identifying key. In the example below, first we obtain the list of clubs by calling a remote service, being each club a Java Bean structure with an attribute per field we need at the presentational level. The whole club list is represented by a Java List container. Once we have the container filled, we store it in the data model (setElement method) under the key 'clubList'. It can be observed that this key is exactly the same as the specified in the repeat-nodeset attribute in the IDEAL2 authoring unit. Also the names of the Java Bean attributes have to be equal to the names used in the presentation (image, href and name).

public class ClubsOA extends BasicApplicationOperation {
 
 public void execute(Context the_context) throws OAException {
 
  List<Club> clubs = DataHolder.getInstance().getClubsInfo();
 
  List<Map<String, String>> data = new ArrayList<Map<String, String>>();
 
  for (Club club : clubs) {			
 
   Map<String, String> aux = new HashMap<String , String> ();
 
   aux.put("name", club.getName());
   aux.put("href", club.getHref());
   aux.put("image", club.getImage());
 
   data.add(aux);
 
  }
 
  the_context.setElement("clubList", data);
 
 }
}

Figure 14. Application Operation: club list


7.1.3. Customizing the presentation layer depending on the Delivery Context

One of the most important functionalities provided by MyMobileWeb is the awareness about the device and web browser used, i.e. the delivery context, thanks to the information provided by the Device Description Repository Service. This functionality can be exploited by authors to customize their application for a broad range of devices. In the example above, you can see how we provide a specific icon for the iPhone. Related to this is the style overriding feature intended to override properties of a style for specific delivery contexts. Using such a feature we can for instance, change the layout and appearance of our menu: vertical for iPhone devices, grid for the rest. Developers can specify by configuration their own device families or reuse those provided by the platform.

menu.clubs {
	img-display: only;
	layout: grid;
	cols: 4;
	border-width: 0;
	background-color1: #ffd8ad;
	background-color2: #f7f6ef;
}

Figure 15. CSS Styles for all devices


menu.clubs {
       img-display:both;	
       align :left;	
       colored: true;
       background-color1:#ffd8ad;
       background-color2:#f7f6ef;
}

Figure 16. Specific CSS Styles for iPhone


7.1.4. Screenshots

Dynamic Menu

Figure 17. Dynamic Menu


7.2. Part II - Tables

<< backtop next >>

7.2.1. Working with Tables

We are going to show how to use tables in the MyMobileWeb framework by focusing on the "Rounds" functionality. The idea is to provide information about each round by displaying the games and the standings. To demonstrate these features, we have designed the presentation below. Such presentation has two sections: one for the games and other for the standings. Each section has a dynamic table controlled by a data model collection specified by means of the repeat-nodeset attribute. As previously noted such an attribute indicates that there will be as many table rows as indicated by a collection that has to be present in the application data model. Our tables are dynamic because they will display different information depending on the round considered. Both tables belong to the 'paginate' class. This means that if the number of rows exceeds the maximum number of rows that device can manage reasonably, they should be automatically paginated by MyMobileWeb. Some of the columns of the standings table are subject to a condition over the Delivery Context to avoid having too many columns in small devices. The corresponding OAs that obtain the games and standings from a remote service are not shown due to space limitations, but they follow the same structure as the one previously described.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="index" title="Rounds"> 
 <resources>
  <link id="icon" rel="shortcut icon" expr="!mymw:belongsTo('iPhone')" type="image/x-icon" href="${myFavIcon}" />
  <link id="iconIPhone" rel="apple-touch-icon" expr="mymw:belongsTo('iPhone')" href="${myFavIcon}" />
  <link rel="stylesheet" id="soccerStyle" href="soccer.css" />
 </resources> 
 <ui>
  <body> 
   <header id="header">
    <include content="Common/generic/common/header" />			
   </header> 
   <section id="main" class="tabs"> 
    <section id="games" title="Games" resourceid="team"> 
     <div>
      <table id="gamesTable" class="soccer paginate">
       <th class="header">
        <td>Date</td>
        <td>Games</td>
       </th>
       <tr repeat-nodeset="games">
        <td><output ref="date" /></td>
        <td><output ref="game" /></td>
       </tr>
      </table>
     </div>
    </section> 
    <section id="standings" title="Standings" resourceid="table"> 
     <div>
      <table id="standingsTable" class="soccer paginate">
       <th class="header">
        <td>Pos</td>
        <td>Name</td>
        <td>W</td>
        <td expr="mymw:deviceWidth() gt 300">L</td>
        <td expr="mymw:deviceWidth() gt 300">T</td>
        <td>Pts</td>
       </th>
       <tr repeat-nodeset="standings">
        <td><output ref="pos" /></td>
        <td class="bold"><output ref="name" /></td>
        <td><output ref="won" /></td>
        <td><output ref="lost" /></td>
        <td><output ref="tied" /></td>
        <td class="bold"><output ref="pts" /></td>
       </tr>
      </table>
     </div>
    </section> 
   </section> 
   <footer id="footer"> 
    <include content="Common/generic/common/footer" />			
    <separator class="line" />
    <include content="Common/generic/common/powered" />				 
   </footer> 
  </body>
 </ui>
</ideal>

Figure 18. Presentation: Sections and Tabs


7.2.2. Tab Layout

section.tabs {
	display-as: tabs;
	tab-not-selected-color: #f7f6ef;
	tab-selected-color: #ffd8ad;
	tab-link-selected-color: white;
	tab-link-not-selected-color: black;
}

Figure 19. CSS Styles for tabs


Defining styles for the previous tables: the background colors of the rows alternate and they will be paginated.

table.paginate {
    paginate:true;
}
 
table.soccer {
    page-position:bottom;
    colored:true;
    background-color1:#ffd8ad;
    background-color2:#f7f6ef;        
    width:100%;
    border-color:#900000;    
    page-control-type:image;
}
 
tr.header {
    color:white;    
    background-color:#ec894b;
    font-weight:bold;
}

Figure 20. CSS Styles for pagination and colors


public class StandingsOA extends BasicApplicationOperation {
 
 public void execute(Context the_context) throws OAException {
 
  List<Map<String, Object>> table = new ArrayList<Map<String, Object>>();
 
   DataHolder dataHolder = DataHolder.getInstance();
   Collection<Club> list = dataHolder.getClubsInfo().values();
 
   int pos = 1;
 
   for (Iterator<Club> iterator = list.iterator(); iterator.hasNext();) {
     Club club = iterator.next();
     Map<String, Object> auxi = new HashMap<String, Object>();
     auxi.put("pos", pos++);
     auxi.put("name", club.getName());
     auxi.put("won", club.getWon());
     auxi.put("lost", club.getLost());
     auxi.put("tied", club.getTied());
     auxi.put("pts", club.getPoints());
     auxi.put("id", club.getId());
     table.add(auxi);   
   }
 
   the_context.setElement("standings", table);
 
 }
}

Figure 21. Application Operation: loading standings


Here we are going to get the games by invoking a service provided by Spanish Profesional Football League

public class GamesOA extends BasicApplicationOperation implements ResultsOAVocabulary {
 
 private final String RESULTS_URL = "http://www.lfp.es/DesktopModules/IWeb/webservice.asmx/ProximaJornada";
 
 public void execute(Context the_context) throws OAException {
 
  Document doc = callService();
 
  List<Map<String, String>> data = getModel (doc);
 
  the_context.setElement("games", data );
 
 }
 
 // More methods...

Figure 22. Application Operation: loading games


7.2.3. Screenshots

The Figure 23 above shows the final result obtained. It can be observed that the two sections are presented in two different tabs. The tab layout is one of the predefined layouts that MyMobileWeb provides. This functionality can be easily achieved by means of a CSS style.

Sections and Tabs

Figure 23. Sections and Tabs


7.3. Part III - Advanced Layouts (Placard)

<< backtop next >>

7.3.1. Placard: Advanced Layout Combining Text and Images

The next example shows how a list of news can be presented to the user. Each news item will contain a title, text content, an accompanying image and optionally other metadata such as author, ratings, etc. To display properly this item set, we have decided to use a placard component. A placard element enables the combination of text, images and other elements in different positions. As usual, for those less capable devices MyMobileWeb will gracefully degrade the placard. MyMobileWeb has different placard layouts that correspond to the most common use cases. The role attribute is used to convey the purpose of each element within the placard, conditioning the place in which it will be finally rendered. Our placard is affected by a repeat-nodeset attribute, as the news are dynamically obtained from an RSS service. In addition this example demonstrates how the range component can be used to display ratings, which are very common these days in web portals.

Placard: rich layouts

Figure 24. Placard: rich layouts


Here we are going to show the image, the subject, author (if available) and date associated to the news item but depending on the delivery context more or less information will be displayed. For example, when the device width is less or equal than 300 the image will not be displayed so we can improve the user experience according to target device (see expr="dcn:deviceWidth() gt 300"). On the other hand we decide to show the rating news so we use the range control for expressing it by means of stars.

Attention: if you need to include a hyperlink inside repeat-nodeset, you should define the value attribute for this a tag. Then you can know the hyperlink was clicked getting the request parameter called VAL.

<a id="read" value="${value}">&#160;read more...</a>

Figure 25. Read more link


String value = ContextUtil.getEventParam(the_context, EventsParams.PARAMETER_VALUE);

Figure 26. Getting event parameter


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ideal2> 
<ideal id="newsList" title="La liga News"> 
 <resources>
  <link id="icon" rel="shortcut icon" expr="!mymw:belongsTo('iPhone')" type="image/x-icon" href="${myFavIcon}" />
  <link id="iconIPhone" rel="apple-touch-icon" expr="mymw:belongsTo('iPhone')" href="${myFavIcon}" />
  <link rel="stylesheet" id="soccerStyle" href="soccer.css" />
 </resources> 
 <ui>
  <body> 
   <header id="header"> 
    <include content="Common/generic/common/header" /> 
   </header> 
   <section id="main"> 
    <div id="p1" class="center common title.common" title="Information" 
         expr="totalItems eq 0 ">
      <image alt="info" id="info" resourceid="info" />
      <p class="bold"><span>Not available RSS Feeds</span></p>
    </div> 
    <div class="news common title.common" title="${newsTitle}" id="para1" expr="totalItems gt 0"> 
     <placard id="placard" class="${newsCard}" repeat-nodeset="news">
      <p role="mymw:subtext" class="news bold">
        <span>${subject}</span>
        <a id="read" value="${value}">&#160;read more...</a>
      </p> 
      <p expr="dcn:deviceHeight() gt 300" role="mymw:subtext" class="news">
        <span class="sub">Date:&#160;</span>
        <span class="sub italic">${date}</span>
        <span expr="!empty(author)" class="sub">&#160;and author:&#160;</span>
        <span expr="!empty(author)" class="sub italic">${author}</span>
      </p> 
      <p expr="dcn:deviceHeight() gt 300" role="mymw:subtext" class="news">
        <range id="rating" expr="dcn:deviceHeight() gt 300" class="rating" start="1" end="5" 
              step="1" ref="rating" />        
      </p> 
      <image expr="dcn:deviceWidth() gt 300" role="mymw:icon-left" class="news" 
             alt="img" id="img" src="${image}" />
     </placard> 
    </div> 
   </section> 
   <footer id="footer"> 
    <include content="Common/generic/common/footer" />			
    <separator class="line" />
    <include content="Common/generic/common/powered" />	 
   </footer> 
  </body>
 </ui>
</ideal>

Figure 27. Presentation: News List


7.3.1.1. Creating Application Operations

This application operation is charge of getting latest news.

public class NewsListOA extends BasicApplicationOperation {
 
 public void execute(Context the_context) throws OAException {
 
  RSSDocument doc = RSSParserFactory.getInstance().getPlugin().parse(DataHolder.getInstance().getNews());
 
  if (doc != null) {
    loadRSS(the_context, doc);
  } else {
    the_context.setElement("totalItems", 0); 
  }
 
 }
 
 private void loadRSS(Context the_context, RSSDocument doc) {
	List<Map<String, String>> news = new ArrayList<Map<String, String>>();
	SimpleDateFormat format = new SimpleDateFormat("EEE, MMM d, yyyy");
	List<RSSItem> list = doc.getItems();
	int cont = 1;
	for (Iterator<RSSItem> iterator = list.iterator(); iterator.hasNext();) {
		RSSItem item = iterator.next();
		Map<String, String> map = new HashMap<String, String>();
		map.put("subject", item.getFilteredTitle());
		String imageURL = item.getImage();
		if (imageURL == null)
			imageURL = "resource/images/unavailable/generic/un.gif";
		map.put("image", imageURL);
		map.put("author", item.getAuthor());
		map.put("date", format.format(item.getDate()));
		map.put("value", Integer.toString(cont - 1));
		if (cont % 2 == 0) {
			map.put("rating", "3");
			map.put("card", "card even");
		} else {
			map.put("rating", "4");
			map.put("card", "card odd");
		}
		news.add(map);
		cont++;
		if (cont > MAX_NUM_NEWS)
			break;
	}
	the_context.setElement("totalItems", news.size());
	the_context.setElement("news", news);
 }

Figure 28. Application Operation: getting latest news


7.3.2. Image Transcoding

With regards to the CSS styles, it is worth to having a look at the style properties assigned to the image within the placard. The transcode property indicates that the image associated to each news item will be automatically transformed to fit in the area reserved to it. It is noteworthy that in this particular case there is no better option than transcodification because such an image comes in an arbitrary size from an Internet RSS feed. Lastly, to avoid image deformation, we have indicated that the aspect ratio should be conserved.

placard.newsCard {
     layout: card;
     width: 100%;     
     border-radius: 6px;
     margin: 1;
}
 
placard.newsOddCard {
     background-color:#ffd8ad;    
}
 
placard.newsEvenCard {	
     background-color:#ec894b;
}
 
div.news {
     background-color: white;
}
 
image.news {
     transcode:true;
     weight-width:25;
     aspect-ratio:true;
     vertical-align: top;
}

Figure 29. CSS Styles for placard and transcoding


7.3.3. Screenshots

Figure 30 shows how the placard has been finally rendered on different devices. When the “read more” hyperlink is activated the entire news item will be showed. Such functionality has been implemented using a simple IDEAL2 authoring unit with a (transcoded) image and a paragraph with dynamic contents.

Screenshots

Figure 30. Screenshots


7.4. Part IV - Carousel of Images

<< backtop next >>

7.4.1. Carousel: Displaying a Dynamic Catalogue of Objects

MyMobileWeb provides an abstract component called carousel intended to display sequentially a catalogue of objects to be selected by the user. This feature can be used in our portal to show club’s image galleries. Figure 31 is an IDEAL2 excerpt declaring a carousel of images about clubs. As our images are provided by an external service as (Flickr) we will use the repeat-nodeset attribute.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ideal2> 
<ideal id="index" title="by Flickr"> 
 <resources>
  <link id="icon" rel="shortcut icon" expr="!mymw:belongsTo('iPhone')" type="image/x-icon" href="${myFavIcon}" />
  <link id="iconIPhone" rel="apple-touch-icon" expr="mymw:belongsTo('iPhone')" href="${myFavIcon}" />
  <link rel="stylesheet" id="soccerStyle" href="soccer.css" />
 </resources> 
 <ui>
  <body> 
   <header id="header"> 
      <include content="Common/generic/common/header" />			 
   </header> 
   <section id="main"> 
    <div class="center common title.common" id="container" title="by Flickr">
     <carousel id="myCarousel" ref="myImage">
       <image id="header" repeat-nodeset="gallery" src="${gallery.current.src}" class="thumbnail"
	     alt="${gallery.current.title}" value="${gallery.current.value}" />
     </carousel> 
    </div> 
   </section> 
   <footer id="footer"> 
    <include content="Common/generic/common/footer" />			
    <separator class="line" />
    <include content="Common/generic/common/powered" /> 
   </footer> 
  </body>
 </ui>
</ideal>

Figure 31. Presentation: Gallery of images


7.4.1.1. Creating Application Operations

Now we are going to get images by invoking Flickr service which returns a list of photos matching some criteria (futbol plus club name).

public class GalleryOA extends BasicApplicationOperation {
 
 public void execute(Context the_context) throws OAException {
 
  String club = (String) the_context.getElement("club");
 
  Club club = DataHolder.getInstance().getClubInfo(club);
 
  Flickr f = new Flickr("78as6d76as87d6a89786asdf5c671d9");
  SearchParameters keyword_search = new SearchParameters();
  String[] search_parameters = { club.getName(), "futbol" };
  keyword_search.setTags(search_parameters);
  keyword_search.setTagMode("all");
 
  List<Map<String, String>> aux = new ArrayList<Map<String, String>>();
  try {
    PhotoList photolist = f.getPhotosInterface().search(keyword_search,30, 1);
    int cont = 0;
    for (Iterator<Photo> iterator = photolist.iterator(); iterator.hasNext();) {
      Photo photo = iterator.next();
      Map<String, String> map = new HashMap<String, String>();
      map.put("src", photo.getThumbnailUrl());
      map.put("title", photo.getTitle()); 
      map.put("value", photo.getMediumUrl());
      aux.add(map);
    }
  } catch (Exception e) {
    log.error(e);
  }
 
  the_context.setElement("gallery", aux);
  }
}

Figure 32. Application Operation: loading images


7.4.2. Defining styles for carousel

Now we are going to apply a center alignment for the carousel component and clear an area around the images applying the padding property.

image.thumbnail{    
    padding:1;
    vertical-align: middle;
    transcode:true;
    width:75;
    aspect-ratio:true;
}

Figure 33. CSS Styles for images


7.4.3. Screenshots

Figure 34 shows how the carousel has been finally rendered on different devices.

Screenshots

Figure 34. Screenshots


7.5. Part V - Statistical Graphics

<< backtop next >>

7.5.1. Developing Statistical Graphics for mobile devices

MyMobileWeb includes an extension library which provides the capability to render statistical graphics for multiple devices in different formats: vector (SVG) or raster images. The library supports different kind of graphics: pie, bar, scatter, etc. The example below demonstrates how easily we can support the statistics functionality required for our portal. A component called barchart must be included. Then, we use the src attribute to convey the data source (XML file) to be used. In this particular case we want to show a bar chart which depicts the number of championships (national and European) won by the different clubs throughout history. We need also to specify the captions in each axis and the corresponding legends.

<chart id="data" type="BarChart"> 
 <data>
   <serie name="Leagues">
     <item y="31"/>
     <item y="19"/>
     <item y="9"/>
     <item y="6"/>
     <item y="2"/>
     <item y="1"/>
   </serie> 
   <serie name="Champions">
     <item y="9"/>
     <item y="3"/>
     <item y="0"/>
     <item y="0"/>
     <item y="0"/>
     <item y="0"/>
   </serie>
 </data> 
 <axes>
   <axisx name="Club">
     <value>Real Madrid</value>
     <value>Barcelona</value>
     <value>Atletico</value>
     <value>Valencia</value>
     <value>Deportivo</value>
     <value>Sevilla</value>			
   </axisx>	   
 </axes> 
</chart>

Figure 35. XML data source: series and axis


The platform tries to adjust the graphic to the display but what happens when the device changes the orientation? We include a Javascript code for updating the graphic when the orientation changes. We can add an event listener to orientation change events so when it happens we will invoke the Rendering Engine module to create a new statistical graphic with new measures via AJAX.

reload = function () {			
 
	var params = {};			
	params["fid"] = 'barchart';
	params["aj"] = 1;	
 
	var callbacks = {
		onsuccess: function(xhr) {			
			mymw.ui.setFragment("container", xhr.responseText); 
		},
		onerror: function(xhr) {			
			mymw.ui.setFragment(id, "Unable to get contents");
		}
	};
 
	mymw.ajax.submit("POST", _MYMW_CTX_NAME + "DH?", params, callbacks);
 
} 
 
mymw.orientation.addObserver( function() { reload(); } );

Figure 36. Updating the graphic


This Javascript code is only included when the target device supports orientation changes and its display is not square (see expr="mymw:propertyValue ('supportedOrientations')['90'] and dcn:deviceWidth() != dcn:deviceHeight()"). In addition we need to include the orientation and user interface modules.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2PlusCharts>
<ideal id="barchar" title="Statistics">
  <resources>
    <link id="icon" rel="shortcut icon"	expr="!mymw:belongsTo('iPhone')" type="image/x-icon" href="${myFavIcon}" />
	<link id="iconIPhone" rel="apple-touch-icon" expr="mymw:belongsTo('iPhone')" href="${myFavIcon}" />
	<link rel="stylesheet" id="soccerStyle" href="soccer.css" />
	<script type="text/javascript" module="http://morfeo-project.org/mymobileweb/modules#Orientation" />
	<script type="text/javascript" src="script/ISO-8859-1/All/mymw-ui_min.js" />
	<script	expr="mymw:propertyValue ('supportedOrientations')['90'] and dcn:deviceWidth() != dcn:deviceHeight()" 
	        type="text/javascript" src="myScript/update.js" />
  </resources>
  <ui>
	<body>
	  <header id="headerSection">
		<include content="Foot/generic/foot/header" />
	  </header>
	  <section id="mainSection">
		<div id="container" class="center nowrap">
			<barchart id="chart" alt="Leagues" src="resource/charts/teams/barchart.xml" ref="selectedBar" class="myChart">
			  <label>List of winners</label>
			  <caption axis="x">Club</caption>
			  <caption axis="y">Number</caption>
			</barchart>
		</div>
	  </section>
	  <footer id="footerSection">
		<include content="Foot/generic/foot/foot" />
		<separator class="line" />
		<include content="Foot/generic/foot/powered" />
	   </footer>
    </body>
  </ui>
</ideal>

Figure 37. Presentation: Statistics


7.5.2. Applying styles to charts

We can indicate the position where the legend will be displayed by means of the legend-position property.

charts.myChart {
     height:90%;
     width:90%;
     legend-position: down;
}

Figure 38. CSS Styles for charts


7.5.3. Screenshots

Figure 39 shows statistical graphics for different devices.

Screenshots

Figure 39. Screenshots


7.6. Part VI - Forms

<< backtop next >>

7.6.1. Working with Forms

In this presentation we design a form to introduce a name and e-mail address and finally a telephone, number of tickets and date's match can be included optionally. We need to validate the data filled by the user. How could I do this? The platform executes automatic validation that can be local (resolved in scripting language) or remote (using the validation information generated previously). How should I indicate the kind of validations? It's very easy, the validations are defined by means of W-CSS styles (E.g. required:true). The validations can be: required, format, type and range validations. In this case, we have decided to use required and format. The full name and e-mail address are required but the telephone number must satisfy a numeric format. There are error messages for automatic validations but you can modify them if you want. The messages support variable substitution involving local parameters and context variables specified by expression languages.

Now we are going to simplify the task of filling forms by means of the recommendations. What does it mean? It's a servlet that receives the term and returns a JSON object composed of matchings. In runtime, a Javascript library loads this object and shows the recommendations automatically. In this example, the servlet has a list of teams.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="index" title="Tickets">
	<behaviour>
		<listener event="click" target="dateField" function="onselect_dateField(y,m,d)" />
	</behaviour>	
	<resources>		
		<link rel="stylesheet" id="soccerStyle" href="soccer.css" />
		<script module="http://morfeo-project.org/mymobileweb/modules#Orientation" />		 
		<script module="http://morfeo-project.org/mymobileweb/modules#Autocompletion" />
		<script	module="http://morfeo-project.org/mymobileweb/modules#Recommendation" />
		<script type="text/javascript" src="myScript/calendar.js" />
	</resources>
	<ui>
		<body>
			<header id="headerSection">
				<include content="Foot/generic/foot/header" />
			</header>
			<section id="mainSection">
				<div id="p1" class="register common title.common" title="Buy Tickets">				
					<input id="name" about-class="foaf:Person" ref="name" 
					       about-prop="foaf:name" class="req register">
						<label class="bold">Full name:</label>
					</input>
					<input id="email" about-class="foaf:Person" ref="email"
					       about-prop="foaf:mbox" class="req register">
						<label class="bold">Email:</label>
					</input>
					<input id="telephone" about-class="foaf:Person"
						   ref="telephone" about-prop="foaf:telephone"
						   validationtype="Integer" class="telephone register">
						<label>Telephone:</label>
					</input>
					<range id="count" start="1" end="5" step="1" ref="count" class="req">
						<label class="bold">Tickets:</label>
					</range>
					<input id="team" ref="team" class="req register"
						   recommendations="true" recommendationsURI="/Soccer/Team">
						<label class="bold">Against:</label>
					</input>				
				</div>
				<div id="p1_date" class="calendar common">
					<inputDate ref="date" class="req clientcalendar" id="dateField">
						<label id="date">Date:</label>
					</inputDate>			
				</div>						
				<div id="p2" class="send center common">
					<submit id="send" value="Buy" />
				</div>
			</section>
			<footer id="footerSection">
				<include content="Foot/generic/foot/foot" />
				<separator class="line" />
				<include content="Foot/generic/foot/powered" />
			</footer>
		</body>
	</ui>
</ideal>

Figure 40. Presentation: Forms


7.6.2. Validations by means of W-CSS styles

For this presentation we have decided to use a grid layout with two columns (see div.register). If you want to indicate that an input is required you need to set the required property to true. The platform shows a mark close the input's label. Finally, we have designed a numeric format for the telephone: zero or more numeric characters (input-format:"\*N")

div.register {
    layout:grid;
    cols:2;
    white-space: nowrap;
}
 
input.req {
    required: true;
}
 
input.register {
    size: 15;
}
 
input.telephone {
    input-format:"\*N";	
}

Figure 41. CSS Styles for forms


7.6.3. Screenshots

Figure 42 shows a form for different devices.

Screenshots

Figure 42. Screenshots


8. Maps Tutorial

<< back top next >>

8.1. Introduction

MyMobileWeb includes an UI component called map which lets authors embed a map viewer in IDEAL2 pages. This component is especially designed for using AJAX although for delivery contexts that don't support it the platform renders it like static maps with a set of controls. The map viewer can get maps from different providers like Google Maps, Open Street Map and WMS services in general. A developer can benefit from a set of functionalities: clustering of place marks, routes, photo overlays, etc...

In following sections we are going to explain different examples working with maps.

8.2. Showing placemarks

In this section we are going to display a map with a set of place marks. Setting the provider attribute we can choose our favourite map provider, e.g: Google Maps or Open Street Map. In this example, the developer only indicates the center of the map by means of the role maps:mapcenter and a set of place marks (labeled coordinates in WGS-84 format). If a developer provides a number of place marks very high the platform will apply a clustering algorithm grouping close points (imagine hundreds of marks in the same view in a mobile environment).

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="in" title="Map">

 <resources>			    		
  <link rel="stylesheet" id="zatStyle" href="soccer.css" />		
 </resources>

 <ui>
  <body>

   <section id="main">						
    <div id="container" class="center">

     <map id="myMap" zoomLevel="15" ref="myMark" controls="true" class="example" provider="Google">

      <placemark id="mapCenter" role="maps:mapcenter">
       <point>
	<coordinates>${mapCenter.latitude},${mapCenter.longitude}</coordinates>
       </point>
      </placemark>		

      <placemark id="myPoints" repeat-nodeset="placemarks" value="${placemarks.current.value}">
       <label>${label}</label>							
       <point>									
	<coordinates>${latitude},${longitude}</coordinates>
       </point>
      </placemark>						

     </map>

    </div>				
   </section>

   <footer id="footerSection">
    <include content="Foot/generic/foot/foot" />			
   </footer>

  </body>
 </ui>
</ideal>

Figure 43. Presentation: Place marks


8.2.1. Creating Application Operations

Now we are going to get place marks by invoking Zaragoza END POINT service which returns a list of POI's.

public void execute(Context the_context) throws OAException {

  List<Map<String, String>> placemarks = SPARQLEngine.getInstance().getPlaceMarks();

  int cont = 0;
  for (Map<String, String> placemark: placemarks) {
    placemark.put("value", Integer.toString(cont++));
  }

  the_context.setElement("placemarks", placemarks );

  Point center = new Point();
  center.setLatitude (Constants.CENTER_LAT);
  center.setLongitude (Constants.CENTER_LNG);

  the_context.setElement("center", center );

}

Figure 44. Application Operation: loading place marks


8.2.2. Map Styles

We can indicate a set of layers that will be displayed by means of CSS styles (layers depend on the provider).

map.example {
   layers: streetview, roadmap;
}

Figure 45. CSS Styles for map


8.2.3. Screenshots

Figure 46 shows how the map has been finally rendered on different devices.

Screenshots

Figure 46. Screenshots


8.3. Displaying photooverlays

In this presentation we are going to show a clickable photo over a map. In this case, we have to define a photooverlay tag with two children: the icon and the photo (using the role attribute). Defining the ref attribute we can know the photo that was clicked because of an event was thrown from the client (we could define a flow based on this interaction, for example to show information about the photo). In this example we use Open Street Map as our provider of maps.

<map id="myMap" zoomLevel="14" ref="myOption" provider="OpenStreetMap">

 <placemark id="mapCenter" role="maps:mapcenter">							
  <point>
   <coordinates>${mapCenter.latitude},${mapCenter.longitude}</coordinates>
  </point>
 </placemark>						

 <photooverlay id="photo">
  <label>${photo.title}</label>							
   <image id="ph" role="maps:photo" alt="photo" src="${photo.src}" class="thumbnail"/>
   <image id="icon" role="maps:icon" alt="icon" src="${photo.src}" class="icon"/>
   <point>
    <coordinates>${photo.latitude},${photo.longitude}</coordinates>
   </point>
 </photooverlay>
						
</map>

Figure 47. Presentation: Photo Overlay


8.3.1. Image Styles

We will use the transcoding module to generate the icon and the photo with the suitable width and height for each delivery context.

image.thumbnail {
   transcode: true;	
   width: 75;		
   aspect-ratio: true;
}

image.icon {
   transcode: true;
   height: 40;
   width: 40;		
   aspect-ratio: false;
}

Figure 48. CSS Styles for images


8.3.2. Screenshots

Figure 49 shows how the photo is displayed over the map.

Screenshots

Figure 49. Screenshots


8.4. Tracing routes

Here we are going to show the route between two points using the kindness of MyMobileWeb. A developer may specify the origin and destination either as civil address or as WGS-84 coordinates, in addition a developer can define a set of waypoints or stopovers which define the route, the difference between both is that the waypoints are not displayed.

Automatically the platform provides different views: the route over the map, textual description and the street view of the current point. In addition, users can toggle among different travel modes by means of a set of buttons displayed over the map (driving, walking,..).

Note

This functionality is only available for desktop browsers, iPhone and Android platforms.

<map id="myMap" zoomLevel="15" provider="Google">
 
 <placemark id="mapCenter" role="maps:mapcenter">
  <point>
   <coordinates>${mapCenter.latitude},${mapCenter.longitude}</coordinates>
  </point>
 </placemark>		
 
 <route>
  <placemark id="stop" repeat-nodeset="route" role="${route.current.role}">
   <label>${label}</label>       
   <point>											      
    <coordinates>${latitude},${longitude}</coordinates>
   </point>
  </placemark>						
 </route>	
 
</map>

Figure 50. Presentation: Routes


8.4.1. Creating Application Operations

Calculating the origin and destination of the route.

public void execute(Context the_context) throws OAException {
 
  Point center = new Point();
  center.setLatitude (Constants.CENTER_LAT);
  center.setLongitude (Constants.CENTER_LNG);
 
  the_context.setElement("center", center ); 
 
  List<Map<String, String>> route = new ArrayList<Map<String, String>>();
 
  Map<String, String> place = new HashMap<String, String>();
  place.put("role", "maps:origin");
  place.put("label", origin.getAddress());
  place.put("latitude", origin.getLatitude());
  place.put("longitude", origin.getLongitude());
  route.add(place);
 
  place = new HashMap<String, String>();
  place.put("role", "maps:destination");
  place.put("label", destination.getAddress());
  place.put("latitude", destination.getLatitude());
  place.put("longitude", destination.getLongitude());
  route.add(place);
 
  the_context.setElement("route", route);

}

Figure 51. Application Operation: setting origin and destination


8.4.2. Screenshots

Figure 52 shows a route displayed on a map.

Screenshots

Figure 52. Screenshots


8.5. Input locations

A typical use case is to introduce locations in applications in which users can lose a lot of time. MyMobileWeb incorporates an UI component that provides a map in which users can locate an address easily. In addition, the platform will set the coordinates (in WGS-84 format) on context and developers can get it (imagine users introducing latitude and longitude in the page).

Note

The link that lets to see a map is only displayed for desktop browsers, iPhone and Android platforms, for the rest of delivery contexts the link is not rendered.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="index" title="Paso 1">
 
 <resources>		
  <link rel="stylesheet" id="myStyle" href="pleasefix.css" />		
 </resources>
 
 <ui>
  <body>
 
   <section id="main">				
 
    <div class="native common title.common" title="Localización">
     <inputLocation id="inpLoc" ref="address" class="pleasefix" provider="Google">
      <label>Address:</label>
     </inputLocation>					
    </div>			
 
    <div class="common">
     <submit id="next" value="Siguiente" />
    </div>		
 
  </section>
 
  <footer id="footer">
   <include content="Foot/generic/foot/foot" />	
   <separator class="line" />
   <include content="Foot/generic/foot/powered" />
  </footer>
 
 </body>
</ui>
 
</ideal>

Figure 53. Presentation: InputLocation


8.5.1. Creating Application Operations

In this example we need to know the coordinates associated with the address that an user have introduced. This information is available in context automatically, MyMobileWeb initializes a java.util.Map that contains the address, latitude and longitude whose key in context is defined in the attribute ref by the authors. How it works? MyMobileWeb gets the coordinates from the provider API in rich delivery contexts or by invoking a Google Geocoding Service for the rest.

public void execute(Context the_context) throws OAException {
 
   Map ref = (Map) the_context.getElement ("address");
 
   String latitude = ref.get (InputLocationVocabulary.LATITUDE);
   String longitude = ref.get (InputLocationVocabulary.LONGITUDE);
   String addr = ref.get (InputLocationVocabulary.ADDRESS);

}

Figure 54. Application Operation: getting locations


8.5.2. Screenshots

Figure 55 shows an input location control.

Screenshots

Figure 55. Screenshots


9. Media Tutorial

<< back top next >>

9.1. Introduction

In this section we are going to introduce the media element which allows to render different media resources (video, audio, …) in accordance with the restrictions imposed by the delivery context.

Following subsections show two examples: using static sources and dynamic sources obtained from Youtube.

9.2. Different representations of the same media

In this case we are going to use a media element which is composed of two representations, one of them is a Flash Video and the other is a streaming video in 3gpp format. The platform automatically knows that formats are supported by the set of media players installed in the target device. In this way, a developer only needs to provide a set of representations of the same element and it is responsibility of MyMobileWeb instantiates the specific media player for each media type.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="in" title="MyMW-Video">

 <resources>			    		
  <link rel="stylesheet" id="zatStyle" href="soccer.css" />		
 </resources>

 <ui>
  <body>

   <section id="main">						
    <div id="container" class="center">
	
     <media id="myVideo" poster="http://i.ytimg.com/vi/7QWThlpRpYg/0.jpg">
       <source src="http://www.youtube.com/v/7QWThlpRpYg?f=videos&amp;app=youtube_gdata" 
               type="application/x-shockwave-flash" />
       <source src="rtsp://v5.cache1.c.youtube.com/CiILENy73wIaGQmIpVFahpMF7RMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp" 
               type="video/3gpp" />
       <fallback>
          <p><span>You cannot watch videos</span></p>
       </fallback>
     </media>

    </div>				
   </section>

  </body>
 </ui>
</ideal>

Figure 56. Presentation: Static sources


9.2.1. Screenshots

Figure 57 shows how the element media has been finally rendered on different devices.

Screenshots

Figure 57. Screenshots


9.3. Using dynamic sources

Now we are going to get a collection of sources by invoking Youtube API. For this case, we have a dynamic set of sources controlled by a data model collection specified by means of the repeat-nodeset attribute.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ideal2>
<ideal id="index" title="Youtube">

 <resources>			    		
  <link rel="stylesheet" id="pleasefixStyle" href="pleasefix.css" />		
 </resources>

 <ui>
  <body>
	
    <header id="headerSection">
		<include content="Foot/generic/foot/header" />
	</header>	
	
	<section id="mainSection">				
		<div class="vertical center common title.common" title="${video.title.plainText}">										
			<media id="mymedia" poster="${video.mediaGroup.thumbnails[0].url}">				
				<source id="mysource"
					repeat-nodeset="video.mediaGroup.youTubeContents" 
					src="${video.mediaGroup.youTubeContents.current.url}" 
					type="${video.mediaGroup.youTubeContents.current.type}" />					
			</media>
			<trigger id="add" class="novalidate accept" value="Añadir" />
		</div>								
	</section>
		
	<footer id="footerSection">
		<include content="Foot/generic/foot/foot" />	
		<separator class="line" />
		<include content="Foot/generic/foot/powered" />
	</footer>
			
  </body>
 </ui>
</ideal>

Figure 58. Presentation: Dynamic sources


9.3.1. Creating Application Operations

Now we are going to get a video by invoking Youtube API.

public void execute(Context the_context) throws OAException {

    // The previous presentation shows a placard with a set of videos
    String yid = ContextUtil.getEventParam(the_context, EventsParams.PARAMETER_VALUE);

    if (yid != null) {
        com.google.gdata.data.youtube.VideoEntry video = YoutubeFacade.query(yid);

		if (video != null) {
			the_context.setElement("video", video);		
		}
	}

}

Figure 59. Application Operation: getting a video


9.3.2. Screenshots

Figure 60 shows how the element media has been finally rendered on different devices.

Screenshots

Figure 60. Screenshots


This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License