UI API

This article demonstrates advanced usage of PlacesAPI including the UI API.

Contents

Searching for places

The examples in Getting Started with Places API display data, using hard-coded place ids. However, the widget classes nokia.places.widgets.SearchBox and nokia.places.widgets.CategorySearch from the UI-oriented part of the Place API offer a flexible way of getting place data, and therefore place ids.

SearchBox

SearchBox provides an edit box, where the Web site user can enter a search term and run a search by hitting the Return key or clicking on the button Go. The search term is plain text that contains a street address (for example, "96 Euston Road, London"), a place name (for example "British Museum"), or a broader category name such as "restaurant", or "pizza". The widget picks up this text from the edit box and submits a request to the back-end Places server. The results include place ids for every place found. A place id can be used when instantiating the Place class or when calling its method setPlaceId() to display the full details of a place.

To embed place search functionality in a Web page:

  • instantiate the Places API SearchBox class
  • implement the callback to process the search results

The working code below shows the <body> of an HTML page that includes:

  • an element to hold a search box, where users can enter a search term
  • a list element in which the results of the search are to be displayed.
  • a <script> element that defines the functionality of the example

In fact, <script> merely instantiates nokia.places.widgets.SearchBox with a few parameters:

targetNode this is the id of the element from which the widget is to pick up the search criteria entered by the user and where suggestions are shown as the user types
searchCenter this is a function that must return an object with the latitude and longitude of the starting point for the search; the search is run in widening circles starting at this location; when the results are presented to the user, they are ordered by relevance to the search criteria and include the distance from the search center
onResults this a function that handles the search results which it receives as the argument data, an array containing information about places matching the user's search criteria (see also below); for each element in the array, the function creates a list element and fills it with the place name, then adds it to the <ul> element with the id 'results'

The object data passed to the onResults consists of elements with the following structure:

  {
    viewId: 'mbc04bl15:20110927130338239:0007307',
    label: 'results'
    results:[  //an array of result objects
        {
            distance: 1359, 
            place: { 
                name: 'Ristorante Marinelli',
                placeId: '276u33d8-e2482cc709e64ec68b55e3c233405f0a'
                location: { ... },
                ratings: { ... }
                
                ...
            }
        },
        {
            distance: 1410,
            place: { ... }
    ]
  }
        

The elements in this structure are:

  • distance – distance of the place from the search center
  • place – an object documented in the API reference under Data API as nokia.places.objects.Place and it includes the following elements:
    • name – the name of the place
    • placeId – the id of the place in Nokia Places database, needed to retrieve full details of the place
    • location – includes address
    • ratings – user/visitor rating of the place

For a complete documentation of the contents of nokia.places.objects.Place, please consult the API reference, however the details above are important for you to understand how the function onResults iterates through data and extracts place names.

<body>
    <div id="searchbox"></div>
    <ul id="results"></ul>
    
    <script>
    // Initialize search box:
    var searchBox = new nokia.places.SearchBox ({
        targetNode: 'searchbox',
        searchCenter: function () {
            return {
                latitude: 52.516274,
                longitude: 13.377678
            }
        },
        onResults: function (data) {
            renderResults (data);
        }
    });
    
    // Handle the results of the search. This callback function receives
    // the raw places data as an array. For each element in this array, 
    // it creates an HTML list element and fills it with the name of the 
    // place:
    function renderResults (data) {
        var previewList = document.getElementById ('results');
        previewList.innerHTML = '';
        
        var results = data.results;
        
        for (var i = 0, l = results.length; i < l; i++) {
            var result = results[i];
            var resultLi = document.createElement ('li');
            resultLi.innerHTML = result.place.name;
            previewList.appendChild (resultLi);
        }
    }
    </script>
</body>

This example outputs a static list of place names on the HTML page just below the search box.

CategorySearch

Like SearchBox, this widget also allows the Web user to get place data, but the searches it supports are based on POI (Place of Interest) categories. The widget's user interface shows a number of category icons and you can simply click on one of them to run a search.

We can adapt the SearchBox example for a simple demonstrate of how to run a category search.

First, let us change the <div> elements:

<div id="categorysearch"></div>
<ul id="results"></ul>            

After that, the script needs to create an instance of CategorySearch, giving it a target node, a searchCenter function and an a function to call when the results are ready. This last function can be identical to renderResults() we used in the SearchBox example.

var csSearchBox = new nokia.places.widgets.CategorySearch({
    targetNode: 'categorysearch',
    searchCenter: function () {
        return {
            latitude: 52.516274,
            longitude: 13.377678
        }
    },
    onResults: function (data) {
        renderResults (data);
    }
});            

Even though the user must click on a category icon to trigger a search, the results (if any) are displayd as a list underneath the <div> with the id "categorysearch". Again, it is a static list.

In the next section, however, we look at how to make the initial search results interactive so that the user can click on a place name and view the full details.

Displaying place details

The scenario in this article expands on Searching for places. The Web user can run a search from a search box, view the initial results as a list, but then he/she can click on an item in the list to view the full details of a place. The added bonus of this scenario is that it offers a simple introduction to event handling in the Places API.

On the Web page, the search box and the initial results appear on the left-hand side, while the details of the place the user selects on the right. To achieve this, the top of the <body> of the page contains these elements:

<div style="width: 32%; float: left;">
    <div id="searchbox"></div>
    <ul id="results"></ul>
</div>
<div style="float: left" id="detail"></div>      

These HTML elements set the layout, but there must also be a <script> element to define the functionality. To create an interactive list of search results with clickable place names, it uses nokia.places.widgets.SearchBox in conjunction with nokia.places.widgets.PlaceList. It first instantiates PlaceList with the following parameters:

targetNode contains the id of the HTML element where the list of places is to appear
perPage indicates how many items are to be shown per page (depending on the size of the search results, the list may occupy more than one page)
events an array parameter that defines what events to associate with the list of results and how to handle them; we want to handle mouse clicks on place names, so there is only one element in the array with the following parameters:
  • rel – the value of the rel attribute in the HTML element(s) to which the event is related; the class PlaceList uses a template named nokia.general.placelist provided as part of the Places API that defines an HTML list to hold the search results, where each item includes a paragraph element (<p>) with the attribute rel set to 'nokia-place-name'; when the template is rendered on the page, each list element is populated with the search results data and the paragraph with the attribute rel receives the name of the place; see also Template attribute referenc e (jsMotif)
  • name – the name of the event to handle; the supported event names are 'keydown', 'keyup', 'keypress', 'click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'mouseenter', 'mouseleave', 'blur', 'change', 'focus', 'reset', 'select', 'submit', 'abort'
  • handler – a function to be called when the event has been fired (when the Web user has clicked on a place name in the results list); this handler creates an instance of nokia.places.widgets.Place, passing to it the id of the place the user selected from the results and the id of the DOM node where the details are to be shown

Next, <script> instantiates nokia.places.widgets.SearchBox much as in Searching for places, except onResultsnow simply calls placeList.setData(). In other words, onResults passes the results it has received on to the available instance of nokia.places.widgets.PlaceList, which displays them, using the template nokia.general.placelist and associating the list elements with the click event handler.

Here is the complete code listing for the <script> element:

<script>

    // Initialize a PlaceList to create a clickable 
    // list of search results. When the user clicks
    // on a place name, the handler function gets the
    // corresponding place details and displays them 
    // in the 'detail' div:
    var placeList = new nokia.places.widgets.PlaceList ({
        targetNode: 'results',
        perPage: 5,
        events: [{
            rel: 'nokia-place-name',
            name: 'click',
            handler: function (jsonObj) {
                var pp = new nokia.places.Place ({
                    placeId: jsonObj.placeId,
                    targetNode: 'detail'
                });
            }
        }]
    })

    // Initialize search box:
    var searchBox = new nokia.places.widgets.SearchBox ({
        targetNode: 'searchbox',
        searchCenter: function () {
            return {
                latitude: 52.516274,
                longitude: 13.377678
            }
        },
        onResults: function (data) {
            placeList.setData(data);
        }
    });

</script>   

When the page is displayed and the user has run a search for 'Hilton London', for example, the results appear as in the figure below.

Figure 1. User interface with initial results

For each item in the list, a category icon is shown on the left (here, the first icon is for a place/town, the remaining ones are hotel icons), followed by the name of the place, with the address underneath and the customer/user rating to the right. In this case, the results occupy four pages, so the interface offers a menu of page numbers above and below the list. If the user selects the second page by clicking on '2' in this menu, and then clicks on the second item in the list, the display changes to add the details of the selected place:

Figure 2. User interface with detail display

The full details are rendered using another template that is provided by default with the Places API, nokia.general.place and include the place name, address, contact, and location map, followed by a list of customer reviews underneath. At the bottom, there is a short menu that:

  • allows you to view the place on the map – it presents a more detailed map view than in the photo above
  • share the place on facebook or twitter
  • reserve a room in the hotel

The last menu item expands when the Web user hovers over it with mouse to show a sub-menu of links to sites on which the user can complete a hotel booking:

Figure 3. "Book this hotel" sub-menu

Note that the item "Book this hotel" is available only for those hotels whose place data include reservation URLs.

As you have been able to observe, the use of templates is at the heart of the UI-oriented Places API. Thus far, we have shown examples that use the default templates, but next, we look at the templating engine more closely not only to show what templates are included as standard, but also how you can customize them.

Making sure the widget is ready

The previous articles in this guide show how to search for place data and how to display them. The API makes these tasks easy by providing widgets: Place, SearchBox, CategorySearch and PlaceList. However, it is essential to bear in mind that widgets must be initialized, which involves establishing communication with the Places back end, and then they must be fully loaded, which means loading the templates from the server (or from a custom location) and loading translations from the server and applying them to the templates. This process is asynchronous and there is simply no way to predict how long it may take. Even more critical is the fact that unless a widget is fully initialized and loaded, you cannot call its methods, so you cannot examine or set data, therefore you can not display data, at least not until the widget is ready.

For this reason, the widget parent class (nokia.places.widgets.Widget ) and therefore alsoPlace, SearchBox, CategorySearch and PlaceList support an initialization parameter named onReady.

The value of onReady is a callback function. It is guaranteed to be called as soon as the widget is fully initialized and loaded, and thus, when it is safe to call its methods. To show how it works, we can modify the example

<script>

    // Initialize a PlaceList to create a clickable 
    // list of search results. When the user clicks
    // on a place name, the handler function gets the
    // corresponding place details and displays them 
    // in the 'detail' div:
    var placeList = new nokia.places.widgets.PlaceList ({
        targetNode: 'results',
        perPage: 5,
        events: [{
            rel: 'nokia-place-name',
            name: 'click',
            handler: function (jsonObj) {
                var pp = new nokia.places.Place ({
                    placeId: jsonObj.placeId,
                    targetNode: 'detail'
                });
            }
        }]
    })

    // Initialize search box:
    var searchBox = new nokia.places.widgets.SearchBox ({
        targetNode: 'searchbox',
        searchCenter: function () {
            return {
                latitude: 52.516274,
                longitude: 13.377678
            }
        },
        onReady: function () {
            this.registerPlaceList(placeList);
        }
    });

</script>   

You may have noticed that this example is very similar to that in Displaying place details, the only difference being onReady. The function which is the value of onReady binds the place list to the search box, which causes place data to be rendered by the place list. This code guarantees that the SearchBox widget is fully initialized and loaded before the data are rendered for display.

Integration with Nokia Maps API

The widget classes in the Places API support an easy way to make use of the Nokia Maps API. Imagine a scenario in which a Web user pans around an interactive map to find Vietnamese restaurants. The user centers the map on the town of choice, then types in "Vietnamese restaurant" into the search box and kicks off the search. Soon, a list of places appears on the page, but also the map displays a number of markers. If the user now clicks on a place name in the list, an info bubble pops up in the map near the icon corresponding to that place. This allows the user to read the details of the place on the page and also view its location on the map.

To support scenarios such as this, the classes SearchBox, Place, and PlaceList have an initialization parameter named map, and Place and PlaceList include methods named displayOnMap().

The parameter map holds a reference to an instance of the Nokia API's map.Display. SearchBox uses this parameter automatically to obtain the coordinates of the searchCenter: it takes them from the center of the current map view. If the user moves the map, these coordinates change and consequently a new search with the same search term is likely to produce different results. PlaceList uses the parameter map to show places as markers in the map, while Place, can display place details in an info bubble next to the appropriate marker.

Several steps are required to implement an application that uses both Nokia's Places and Maps APIs and we explain them below.

Implementation – <head>

First, you need to reference the library files for the respective APIs by adding <script> elements in the <head> of the Web page. For the Places API, this is exactly as shown in Getting started with Places API, and you can use the following <script> element to reference the Maps API library :

<script type="text/javascript" 
    src="http://api.maps.nokia.com/2.0.0/jsl.js?
    map=auto&search=none&routing=none&positioning=none&ui=none" />

Note the query parameters in the URL: they allow you to select the user interface and map behavior components, although this example simply requests the automatic map display and ensures that search, routing and positioning are not included. For full documentation of the supported parameters and possible values, please refer to the section "Packages and Detection" under Advanced Usage in the Maps API documentation on line.

Implementation – <body>

The <body> of a page that implements the scenario needs to define the HTML elements in which to display the search box, the search results and the map:

<div id="mapSearchbox"></div>
<div id="mapPlacelist"></div>
<div id="map" style="width: 700px; height: 800px;"></div>
<div style="clear:both"></div>

Next, we need a <script> element with the JavaScript code that defines the functionality. The first thing to do here, is to get an instance of the map display:

var map = new nokia.maps.map.Display(document.getElementById("map"), {
    'zoomLevel': 10, //zoom level for the map
    'center': [52.51, 13.4], //center coordinates,
    components: [new nokia.maps.map.component.Behavior(),
        new nokia.maps.map.component.TypeSelector(),
        new nokia.maps.map.component.ZoomBar(),
        new nokia.maps.map.component.RightClick()
});

The variable map holds a reference to an instance of map.Display. The map is shown on the page inside the element with the id "map". In addition, the initialization arguments specify the zoom level, the coordinates of the map center, and then a number of components to ensure that the map is fully interactive. For further information, please refer to the Maps API documentation on line.

Now, we can use map to instantiate the Places API widgets.

The scenario requires a search box, but we want it to use the center of the visible map as the search center. The easiest way to do that is to make our reference to map.Display the value of the SearchBox initialization parameter map:

var sb = new nokia.places.widgets.SearchBox({
    targetNode: 'mapSearchbox',
    map: map,
    onResults: function (data) {
        mapPlaceList.setData(data);
    }  
});    

Next, we get an instance of nokia.places.widgets.Place that 'knows' about the map, so that it can later display data relating to the place selected by the user from the search results:

var mapPlaceWidget = new nokia.places.widgets.Place({
    map: map
    });

Finally, we need a PlaceList object to handle the search results is required. Its initialization property map must receive the reference to map.Display and it needs a function to display the places in the list as markers on the map (this function is the value of the property onRenderPage) . The last task is to ensure that when the user clicks on an item in the results list, the details of that item appear in the info bubble next to the item's map marker. This is done via the initialization property events. events has properties of its own:

rel the id of the HTML node to which an event is to be attached (node's rel attribute)
name the name of the event
handler a function that causes the info bubble to be shown on the map
var mapPlaceList = new nokia.places.widgets.PlaceList({
    targetNode: 'mapPlacelist',
    map: map,
    onRenderPage: function(){
        mapPlaceList.displayOnMap();
    },
    events: [
    {
        rel:'nokia-place-name',
        name: 'click',
        handler: function (place) {
            mapPlaceWidget.displayOnMap(place);
        }
    }
    ]
    })

Language support

The Places API library is available a single download (file), but once installed, it supports a number of languages.

Getting started with Places API shows the simplest way to reference the library an then to instantiate the Placewidget without specifying a locale. This causes the library to use the default British English, which means that this is the language of the user interface, the language in which the widget displays all text. To select a different language, you need to include 'locale' among the initialization parameters for a widget, for example here we set the language to Polish when initializing the Place widget:

<script type="text/javascript">
    var place = new nokia.places.widgets.Place({
        placeId: '276u33db-751a77335fcf4e0e80660190aa92f584',
        targetNode: 'place',
        locale: 'pl-pl'
   });
   </script> 

The list below shows the identifiers for all the languages that are currently supported by the Places API. Each identifier is a string consisting of an ISO 369 code and an ISO 3166 Alpha 2 country code.

  • 'cs_cz' – Czech
  • 'da_dk' – Danish
  • 'de_de' – German
  • 'el_gr' – Greek
  • 'en_gb' – English (Great Britain)
  • 'en_us' – English (US)
  • 'es_es' – Spanish
  • 'fi_fi' – Finnish
  • 'fr_fr' – French
  • 'hi_in' – Hindi
  • 'hr_hr' – Croatian
  • 'hu_hu' – Hungarian
  • 'id_id' – Indonesian
  • 'is_is' – Icelandic
  • 'it_it' – Italian
  • 'ko_kr' – Korean
  • 'nl_nl' – Dutch
  • 'no_no' – Norwegian
  • 'pl_pl' – Polish
  • 'pt_br' – Portugese (Brasil)
  • 'pt_pt' – Portugese
  • 'ro_ro' – Romanian
  • 'ru_ru' – Russian
  • 'sk_sk' – Slovak
  • 'sv_se' – Swedish
  • 'th_th' – Thai
  • 'tr_tr' – Turkish
  • 'zh_cn' – Chinense (Simplified)
  • 'zh_hk' – Chinense (Hong Kong)
  • 'zh_tw' – Chinense (Taiwan)

Working with templates

A template is a hierarchy of HTML elements that define a (part of) the user interface and include instructions for populating it with data. The look and feel of the rendered user interface is determined by a style sheet (CSS).

Templating engine and extensions

A module named jsMotif, which is integrated into the Places API, provides the templating engine. Its Template class creates a template instance on the basis of:

  • an HTML string that defines the template structure or ...
  • the id of an HTML element to be used as a template or ...
  • a reference to an existing DOM node to be used as a template or ...
  • a string identifying the template with its full name and namespace

In addition, you can specify the target node, that is the HTML element to which the template is to be applied, and you can specify how events that affect parts of the template are to be handled (in other words, you can set the behavior of the user interface).

Very important to mention here is also the fact that jsMotif defines a number of attributes that can be used in the HTML elements in a template. These attributes allow you specify sub-templates, fill template elements with data, and even show and hide elements, depending on whether the data required to populate them are available. For full details, refer to Template attribute reference (jsMotif).

One of those attributes is fill whose purpose is to fill an HTML element with data. The value of fill can be obtained, using the functions in jsMotif's namespace selector: the functions allow direct access to properties of a Place object in a similar way to XPath.

The class nokia.places.ui.Template and the namespace nokia.places.ui.templateFunctions extend the templating engine. The first defines a template element attribute module through which you can reference a module implementing UI behavior – a number of such modules are provided with the API and are documented in the API reference (see also Modules). nokia.places.ui.templateFunctions provides functions you can use in addition to those in selector to extract data from a Place object.

Anatomy of a template

The following rules apply to a template:

  • it contains a hierarchy of HTML elements
  • the elements can use any standard HTML attributes and the attributes supported by Places API's templating engine to:
    • identify a sub-template
    • fill elements with data from a JSON object representing a Place
    • specify modules that help render an element and/or define its behavior after rendering – for example, a module can create a clickable list of icons representing stars; the user can rate a place by clicking on the stars
    • mark elements as targets for modules or events (such as clicks)
  • in the HTML page part of which the template is to generate, it must be referenced by its parent (or target) element – a Places API template must be identified by its full name including the namespace, for example <div tpl="nokia.general.map"></div>, but a custom template can be defined as an HTML string or as an HTML element in the same page so that it can be referred to by its id, and finally any HTML element with a unique id can be used as a template (see also A custom template below)

Template reference in this guide lists all the standard templates provided with the Places API and discusses them briefly. For example, the template place nests other templates via the attribute tpl. It also displays elements conditionally and fills them, using selectors. searchbox demonstrates the use of the attribute module and rel to mark an element as a module target.

A custom template

This section builds on the material in Templating engine and extensions and Anatomy of a template. Please refer also to Template attribute reference (jsMotif).

Predefined templates can save time and effort, but there may be occasions when a custom template is required. For example, you might have a requirement to make a template that shows the name and address of a place and displays related images.

The data with which the template has to work come from a JSON object similar to the one shown below:

{
    name: 'Le Marfil',
    contact: {
        phone: [{
            label: 'Home away from home',
            value: +1081111111
        ]}
    },
    location: {
        address: {
            city: 'Paris',
            street: 'Rue Auguste Vacquerie',
            house: '4',
            country: 'France'
        }
    },
    images: [
        {
            supplier: {
                name: 'WCities'
            },
            URL: 'http://image.com/image.jpg'
        },
        {
            supplier: {
                name: 'orange'
            },
            URL: 'http://image.com/image.png'
        },           
        {
            supplier: {
                name: 'WCities'
            },
            URL: 'http://image.com/image.gif'
        }           
    ]
}   

Please note that the object above is provided here as a reference for the following discussion and its structure is simplified compared to the structure of data objects the Places API actually retrieves.

The following code creates a paragraph filled with the name of the place.

 <p fill="{name}"></p>

Next, the address, which we can get with a function defined in nokia.places.ui.templateFunctions:

<p fill="{fullAddress()}"></p>

Finally, we need a list of images from the data object, but only those for the provider 'orange'. The following line creates a list item:

<ul each="{images[supplier.name=='orange']}">
    <li fill="{URL}"></li>
</ul>

The assembled template can be defined like this – this is the full <script> and HTML element version:

<script id="myTemplate" type="text/template">
<div>
    <p fill="{name}"></p>
    <p fill="{fullAddress()}"></p>
    
    <ul each="{images[supplier.name=='orange']}">
        <li fill="{URL}"></li>
    </ul>
</div>
</script>

The implications of the above definitions are:

  • the template is the contents of the <script> element and it must be identified by the id of <script>
  • although the template defines a complete HTML node, this node is not rendered on the page (it is not visible), unless the template is referenced in a Places API call
  • to render a page element using this template, it is necessary to define a target node, which is the node to which the template is to be applied

Here is the code that fills the prepared template with data from the received object:

var place = new nokia.places.widgets.Place({
    template: "myTemplate", 
    targetNode: "renderMyTemplateHereId"
});

place.setData (object);

Note that the parameter object passed to the constructor for nokia.places.widgets.Place references our template and the target node. The latter implies that the page contains an element such as this:

<div id="renderMyTemplateHereId"></div>

However, this template is very simple, so you might wish to define it as an HTML string instead:

var myTemplate = '<div><p fill="{name}" 
class="place-name"></p><p fill="{fullAddress()}"></p>
<ul each="{images[supplier.name=='WCities']}"><li fill="{URL}"></li></ul>
</div>';

To apply the template, the constructor for nokia.places.widgets.Place must be passed a reference to it:

var place = new nokia.places.widgets.Place({
    template: myTemplate, 
    targetNode: "renderMyTemplateHereId"
});

place.setData (object);

A further possibility is to use one of the elements from the HTML page as a template. For example, a page is likely to contain a number of <div> elements, and one of them could act as a template (here we reuse the template we have defined earlier):

<div id="pageTop"><p>Fixed content at the top of the page</p></div>
<div id="myTemplate">
    <p fill="{name}" class="place-name"></p>
    <p fill="{fullAddress()}"></p>
    
    <ul each="{images[supplier.name=='WCities']}">
        <li fill="{URL}"></li>
    </ul>
</div>
<div id="renderMyTemplateHere2Id"></div>

All these elements are visible on the Web page. Let us assume that the <div> with the id "pageTop" uses fixed content (here it is only text). The other two <div> elements must be populated with data to be rendered and laid out on the pattern defined by the <div> with the id "myTemplate". The code below makes this happen:
var place1 = new nokia.places.widgets.Place({
    placeId: '276u33db-751a77335fcf4e0e80660190aa92f584',
    template: "myTemplate"
});

var place2 = new nokia.places.widgets.Place({
    placeId: '250u09tv-fc09ac6bdbe340e9b5e2ad78efc814d0',
    template: "myTemplate", 
    targetNode: "renderMyTemplateHere2Id"
});

This code makes no attempt to set place id's dynamically, because we want to keep the focus on template issues. The first call to the Place constructor names the place id and the template, but there is no need to specify a target node: it is implicitly the template's own <div>. In the second, a target node is necessary, otherwise the new data would overwrite those in <div id="myTemplate">.

Please note that to identify a template or target node, for example when constructing a Place instance, you can use the id of the appropriate node directly (as in the code above), or you can use a node reference:

var node = document.getElementById("myTemplate");
...          
var place = new nokia.places.widgets.Place({
    placeId: '276u33db-751a77335fcf4e0e80660190aa92f584',
    template: node
});

Modules

The purpose of a module in Places API is to define the behavior of the user interface when places data have been rendered for display with the help of a template. In addition, some modules assist in the process of data rendering.

Modules are components defined in the namespace nokia.places.ui.modules.

To use a module:

  • reference the module in the template that creates the user interface through the value of the element attribute module (see also Template attribute reference (jsMotif))
  • if the module requires it, ensure that the template elements that are targets for the module are identified by the attribute rel (see also Template attribute reference (jsMotif)) and Api reference, UI API, modules)
  • pass the module initialization parameters to the widget that uses the template, when the widget is instantiated

The template below modifies the one we made in A custom template by making the module List determine the behavior of the list of images: the display is to be paginated, with one image per page, and there is to be a menu showing clickable page numbers. To make this happen, a <div> element with the attribute module wraps <ul> and <ul> itself contains a rel attribute set to "list-data".

<div id="myTemplate_list">
    <p fill="{name}"></p>
    <p fill="{fullAddress()}"></p>
 
    <div module="List">
        <div rel="list-pagination"></div>
        <ul each="{images[supplier.name=='orange']}" rel="list-data">
            <li fill="{URL}"></li>
        </ul>
    </div>
</div>

To display the place data, an instance of nokia.places.widgets.Place is necessary. Its initialization must include the template id and moduleParams for the module List, specifying how many items are to appear on each page. Finally, the place data must be given to the instance of nokia.places.widgets.Place:

var place = new nokia.places.widgets.Place ({
    template: "myTemplate_list",
    moduleParams: {
        'List': {
            perPage: 1
        }
    }
}); 

place.setData(object);

For further information about the available modules and module initialization parameters, pleaser refer to the API reference.

Template attribute reference (jsMotif)

This section documents the complete set of template HTML element attributes supported by the Places API. Most of these attributes are implemented by jsMotif and one, module, is implemented by the Places API class nokia.places.ui.Template.

Note that the values of the attributes each, fill, if, mailto and url can be determined by accessing data held in an available Places API object, using jsMotif.selector or a member of nokia.places.ui.templateFunctions. Both jsMotif.selector or a member of nokia.places.ui.templateFunctions treat the object from which data is to be extracted as a hierarchy whose elements are addressable in a similar way to XPath. This is very clear when using selector, because to access the value of an element, you need to use the full path to the element within the object, naming each element along the path and separating them with a dot (please see the examples below).

The examples that illustrate the documentation below reference elements in the following object:

{
    name: 'Le Marfil',
    contacts: {
        email: [
          {
            label: 'email',
            value: 'info@lemarfil.fr'
          }  
        ]
    },
    location: {
        address: {
            city: 'Paris',
            street: 'Rue Auguste Vacquerie',
            house: '4',
            country: 'France'
        }
    },
    images: [
        {
            supplier: {
                name: 'WCities'
            },
            URL: 'http://image.com/image.jpg'
        },
        {
            supplier: {
                name: 'orange'
            },
            URL: 'http://image.com/image.png'
        },           
        {
            supplier: {
                name: 'WCities'
            },
            URL: 'http://image.com/image.gif'
        }           
    ]
}   

Please note that the object shown above is provided as a reference for the following discussion and its structure is simplified compared to the structure of data objects the Places API retrieves.

Attributes

each
The attribute each takes as its value an array and causes the template node to be replicated and filled with the elements of the array. In the example below, each ensures that a <ul> element is created for every item in media and populated with the value of the item's property supplier.name.
Example:
<ul each="{images}"> <li fill="{supplier.name}"></li></ul>
fill
This attribute fills a node with data (value), which can be taken from a Places API object, but can also include custom text.
Examples:
To access one of the top-level elements such as name, you can simply name it.
<p fill="{name}"></p>
And here is a variation on the previous example, which combines a Place object element and custom text.
<p fill="The name is: {name}"></p>
To access label, you need to use the dot notation.
<p fill="{contacts.email[0].label}"></p>
The next example uses fill in conjunction with if and each.
<ul if="{name=='Le Marfil'}" each="{images}">
    <li fill="{URL}"></li>
</ul>
fill and each allow you to access the contents of every element in an array and you do not need to name it. The array in the example below is businessInformation.paymentMethods, which may be part of a place data object retrieved by the Places API (although not included in the sample object above). paymentMethods is an array of strings such as "American Express", "CB Visa Mastercard", etc. The template code below looks at each item in paymentMethods and fills a list element with the string it contains:
<ul each="{businessInformation.paymentMethods}">
    <li fill="{.}"></li>
    </ul>
Note also that {.} changes the selection scope to the current element in the array. As a result, you can access any member of the current element directly by name without the need to identify the current element first. Consider the following template excerpt, where each is used to iterate through every place element in an array named results, getting the icon URL from the first item under (place) categories, the name of the place and the details of the address, including the country name (specifically location.address.countryName):
<div module="List">
    <div rel="list-pagination"></div>
    <ul each="{results[].place}" rel="list-data">
        <li>
            <img url="{categories[0].iconURL}">    
            <p fill="{name}" rel="nokia-place-name"></p>
            <div class="nokia-place-address">
                <span fill="{street()}"></span><br>
                <span fill="{locality()}"></span><br>
                <span fill="{location.address.countryName}"></span>
            </div>
        </li>
    </ul>
</div>
if
if allows you to define a test and hide or show the node, depending on the return value. In the example below, the entire is shown or hidden, depending on the availability of contact description.
Example:
<div if="{contacts.email[0]}"> 
    <h1>Description:</h1>
    <p fill="{contacts.email[0].value}"></p>
</div>
mailto
This attribute allows you to specify an e-mail address in the href attribute inside an anchor element. In the example below, a filter is used to set e-mail as a contact type of the first contact in the data object, so that the value of mailto is set to the e-mail address. Note that the attribute permits mixing elements values extracted from a Place object and custom text (see also the attribute "fill" above).
Example:
<a mailto="{contacts.email[0].value}" fill="{contacts.email[0].value}"></a>
module
This attribute allows you to specify the name of a Places API module.
Example:
<div module="SearchBox"></div>
rel
rel marks an element as a target for a module (see also the attribute module) or for an event.
Most modules require the rel attribute and its value must be one of the strings supported by the modules (for details please refer to API reference, modules).
Examples:
In the following example, rel identifies an input element as the target for the module SearchBox.
<div module="SearchBox" class="nokia-searchbox">
    <input class="nokia-searchbox-input" type="text"
        rel="searchbox-input"/>
    ...
</div>
When rel identifies an element as a target for an event, the value of the attribute can be any string of your choice, but the same string must be echoed by the value of the rel parameter in the events array supplied as part of the widget instantiation object.
The example below shows the attribute marking a paragraph element as the target for a click event.
<p fill="{name}" class="nokia-place-name"
            rel="name-click"></p>
tpl
tpl allows you to specify a template. The value can be either one of the templates provided with the Places API (in which case, the template name has to be fully qualified with the space name, for example, "nokia.general.address") or the id of a custom template element. Both these possibilities are shown in the examples below
Examples:
<div tpl="nokia.general.name" ></div>
<div tpl="domElementIdOfMyTemplate"></div>
url
The attribute url takes as its value the URL of a resource; it provides the src attribute and its value for images and the href attribute and its value for anchors. Note that the attribute permits mixing elements values extracted from a Place object and custom text (see also the attribute "fill" above).
Examples:
<img url="{categories[0].iconURL}">
<a url="{suppliers[0].supplierURL}" fill="{suppliers[0].supplierURL}"></a>

Template reference

This section offers a reference to the templates provided with the Places API.

The section describes each template and provides a complete listing. Our purpose is both to help you understand the default behavior and also to provide examples that can be used when defining custom templates.

searchbox

The template searchbox defines an HTML page element that displays a search box, where the Web user can enter the search term, a button to trigger a search, and a list element to display search suggestions. The top element within the template body uses the attribute module with the value "SearchBox" to specify the Places API module that handles the behavior of the rendered template.

<div module="SearchBox" class="nokia-searchbox">
    <input class="nokia-searchbox-input" type="text" 
           rel="searchbox-input"/>
    <input class="nokia-searchbox-button" type="button" 
           rel="searchbox-button" value="___places.search.go___"/>
    <div rel="searchbox-list" class="nokia-searchbox-list">
        <div class="nokia-searchbox-list-border"></div>
    </div>
</div>

placeList

The placeList template defines an HTML page element that displays a list with information about a number of places. The information results from a search. Each item in the list is rendered to display various items of information relating to a place. The template supports pagination of the list.

Note that some of the elements in the template are displayed conditionally, depending on the attribute if. Other elements are populated with data on rendering, using functions specified in the value of the attribute fill.

<div module="List">
    <div rel="list-pagination"></div>
    <ul each="{results[].place}" rel="list-data" 
        class="nokia-place-list">
        <li class="nokia-place-list-elem">
            <img url="{categories[0].iconURL}" 
                 class="nokia-place-category">     
            <p fill="{name}" rel="nokia-place-name" 
                class="nokia-place-name"></p>
            <div class="nokia-place-address">
                <span fill="{street()}"></span><br>
                <span fill="{locality()}"></span><br>
                <span fill="{location.address.country}"></span>
            </div>
            <div tpl="nokia.general.rating" if="{placeId}"></div>
        </li>
    </ul>
    <div rel="list-pagination"></div>
</div>

place

The place template is the default template supplied with the Places API library to render full place data. It includes a number of other Places API templates via the attribute tpl.

Note that some of the elements in the template are displayed conditionally, depending on the attribute if. Other elements are populated with data on rendering, using functions specified in the value of the attribute fill.

<div tpl="nokia.general.name" class="nokia-place-header"></div>
<div class="nokia-place-left" if="{placeId}">
    <div tpl="nokia.general.rating"></div>
    <div tpl="nokia.general.address"></div>
    <div tpl="nokia.general.contact"></div>
</div>
<div tpl="nokia.general.map" class="nokia-place-right"></div>
<div class="nokia-place-bottom">
    <div class="nokia-place-opening-hours" 
         if="{extended.businessInformation.openingHours}">
        <strong>___places.bubble.openingHours___</strong><br>
          <p fill="{extended.businessInformation.openingHours}"></p>
    </div>
    <div class="nokia-place-payment-methods" 
         if="{extended.businessInformation.paymentsMethods}">
        <strong>___places.bubble.paymentmethods___</strong>
        <p fill="{extended.businessInformation.paymentsMethods}"></p>
    </div>
    <div if="{images}" tpl="nokia.general.gallery"></div>
    <p class="nokia-place-owner-content" 
        fill="{editorials[supplier.supplierId==OWNER][0].description}"></p>
    <div tpl="nokia.general.premium"></div>
    <div tpl="nokia.general.reviews"></div>
    <div tpl="nokia.general.sharemenu"></div>
</div>

address

The address template defines HTML page elements that display street address, zip/postal code, city and country name.

<strong>___places.incident.whereisit___</strong><br>
<span fill="{street()}"></span><br>
<span fill="{locality()}"></span><br>
<span fill="{location.address.country}"></span>

booking

This template works in conjunction with the module Menu to display the contents of a menu item in the interface generated by the template sharemenu. The menu item is labeled "Book this hotel" and is shown, provided that the place data refers to a hotel and that it includes at least one booking URL.

When the user hovers with the mouse pointer over a menu item created via this template, a sub-menu appears, showing a list of links to sites through which the hotel can be booked. If the user clicks on one of the links in the sub-menu, he/she is then taken to a Web page belonging to the provider of the booking facility and can complete the reservation.

<ul module="Menu" class="nokia-place-booking" 
        if="{links[type=='BOOKING'][0]}">
    <li rel="menu-elem" class="nokia-menu-elem">
        <a class="nokia-menu-headlink">___places.hotelbooking.basic___
        </a>
        <ul each="{links[type=='BOOKING']}" rel="menu-show" 
                class="nokia-submenu">
            <li>
                <a target="_blank" url="{URL}" class="nokia-book-icon">
                    <img url="{supplier.iconUrl}">
                </a>
                <a target="_blank" url="{URL}" class="nokia-book-link">
                    <span fill="{supplier.name}"></span>
                </a>
            </li>
        </ul>
    </li>
</ul>

This template can be included in custom templates that provide their own booking links.

Please see also the description of the module menu in the API Reference.

contact

The contact template defines HTML page elements that display place-related contact details such as telephone number, e-mail, fax and Web site URL.

<div class="nokia-place-contact" if="{contacts[0]}">
    <strong>___places.incident.howtocontact___</strong>
    <p class="nokia-place-phone" 
        fill="{primaryPhone()}"></p>
    <p class="nokia-place-mobile-phone" 
        fill="{primaryMobile()}"></p>
    <p class="nokia-place-fax" 
        fill="{primaryFax()}"></p>
    <p class="nokia-place-email">
        <a mailto="{primaryEmail()}" fill="{primaryEmail()}"></a></p>
    <p class="nokia-place-website-url">
        <a url="{primaryURL()}" 
            fill="{primaryURLLabel()}"></a></p>
</div>

gallery

The template gallery is intended to display a collection of pictures relevant to a place. The template supports display of thumbnails and larger images.

<div module="Gallery" class="nokia-place-gallery">
    <div class="nokia-place-big-img-container">
        <img rel="gallery-big-img" />
    </div>
    <div class="nokia-place-small-gallery">
        <div rel="gallery-previous" 
            class="nokia-place-gallery-previous"></div>
        <div rel="gallery-list" 
            class="nokia-place-gallery-list">
            <img rel="gallery-img" />
            <img rel="gallery-img" />
            <img rel="gallery-img" />
            <img rel="gallery-img" />
            <img rel="gallery-img" />
            <img rel="gallery-img" />
            <img rel="gallery-img" />
        </div>

        <div rel="gallery-next" 
            class="nokia-place-gallery-next"></div>
    </div>
</div>

map

The map template defines an HTML page element that displays a map of the place and map zoom controls.

<div module="Map" class="nokia-place-map">
    <div rel="map-container" class="nokia-place-map-container"></div>
    <a rel="zoom-in" class="nokia-place-zoom-in"></a>
    <a rel="zoom-out" class="nokia-place-zoom-out"></a>
    <div class="nokia-place-map-watermark">
        <span>&copy; NAVTEQ 2010</span><br>
        <a title="Terms of Use" 
          href="http://maps.nokia.com/services/terms">Terms of Use</a>
    </div>
</div>

name

The name template defines HTML page elements that display place identifiers such as name, title, category icon, category (icon).

<img url="{categories[0].iconURL}">     
<p fill="{name}" class="nokia-place-name" rel="name-click"></p>
<p class="nokia-place-name-bottom">
    <span fill="{categories[0].name}" class="nokia-place-category"></span>
    <span if={suppliers[0].supplierUrl} class="nokia-place-source">
    source: <a fill="{suppliers[0].name}" url="{suppliers[0].supplierUrl}"></a>
    </span>
</p>

premium

The premium template defines page elements that display premium content information including provider's name, icon and description. These elements belong to a premium content item, which is one in a list of such items.

Note that some of the elements in the template are populated with data on rendering, using functions specified in the value of the attribute fill.

<div module="Accordion" each="{editorials[supplier.supplierId!=OWNER]}" 
             class="nokia-place-premium">
    <div class="nokia-place-premium-header" rel="accordion-header">
        <div class="nokia-place-premium-provider" 
            fill="{supplier.name}"></div>
    </div>
    <div class="nokia-place-premium-body" rel="accordion-body">
        <img url="{supplier.iconURL}">
        <div fill="{content}" class="nokia-place-premium-content"></div>
        <div class="nokia-place-clear"></div>
    </div>
</div>

rating

The rating template defines a page element that displays a list of customer/user ratings for a place.

<div module="Rating" class="nokia-place-ratings-container">
    <ul rel="rating-list">
        <li rel="rating-star1"></li>
        <li rel="rating-star2"></li>
        <li rel="rating-star3"></li>
        <li rel="rating-star4"></li>
        <li rel="rating-star5"></li>
    </ul>
    <span rel="rating-count" class="nokia-place-rating-count"></span>
</div>

reviews

The reviews template defines an HTML page element that displays a list of customer/user reviews of a place.

Note that other Places API templates are included using that attribute tpl. Some of the template elements are populated with data, using the attribute fill.

<div module="Reviews" if="{meta.items!=0}" class="nokia-place-reviews">
    <ul each="{data}">
        <li class="nokia-place-review">
            <img class="nokia-place-review-vendor-img" url="{supplier.iconURL}">
            <p class="nokia-place-review-metadata" 
                 rel="vendor-click">Posted by <span 
                     fill="{user.name}">a</span> on <span fill="{reviewDate()}">
                 </span></p>
            <div tpl="nokia.general.rating"></div>
            <p class="nokia-place-review-title" fill="{title}"></p>
            <p class="nokia-place-review-body" fill="{description}"></p>
        </li>
    </ul>
    <div class="nokia-place-clear"></div>
</div>

sharemenu

The template sharemenu defines an HTML page element that displays a small menu, allowing the Web user to share the given place. In addition, it includes a menu item labeled "Book this hotel" (for places that offer a booking URL). The behavior of an interface generated from this template is managed via the module ShareMenu, however, the item "Book this..." is created by the template booking and its functionality determined by the module Menu.

<div module="ShareMenu" class="nokia-place-sharemenu">
    <div class="nokia-place-link-container">
        <a rel="sharemenu-link" class="nokia-show-map nokia-share" target="_blank" 
        title="___places.player.seeOnTheMap___">
        ___places.player.seeOnTheMap___</a>
        <a href="#" rel="sharemenu-share" class="nokia-sharemenu nokia-share" 
        title="___places.bubble.menu.share___"></a>
        <div tpl="nokia.general.booking"></div>
    </div>
    <div class="nokia-place-share-container" rel="sharemenu-share-container">
        <a rel="share-facebook" class="nokia-share-fb" target="_blank"></a>
        <a rel="share-twitter" class="nokia-share-tw" target="_blank"></a>
        <input type="text" rel="sharemenu-input">
        <a href="#" rel="sharemenu-cancel">Cancel</a>
    </div>
</div>

Copyright © 2011 Nokia. All rights reserved. Terms and Conditions