Building a mobile website with JSF 2 core and JQuery Mobile 1.0

Friday December 09, 2011 ()

This is to share our experience with the JQuery Mobile 1.0 used with Mojarra JSF 2.1.3. The link below points to the mobile website described in this blog.

https://kahimyang.com/mobile (This website has been updated to JQM version 1.3.2)

The build environment

We used Netbeans 7 to create a regular Web/JSF project with Mojarra 2.1.3. We required no special libraries except for Mojarra itself and the MySQL database connectors. We only made sure we have included JQuery and JQuery mobile in the head section of each mobile page. See below.


        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <link rel="stylesheet"
              href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />

        <script type="text/javascript"
                src="http://code.jquery.com/jquery-1.6.4.min.js">
        </script>

        <script type="text/javascript"
                src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js">
        </script>

The Home Page

A JQuery mobile page may contain several views. Our home page below has 2 views identified by data-role="page" in line 37 and 103. The default active visible view is the first view in the page. Our second view (id="about") is activated as modal dialog as seen in line 94 (data-rel="dialog").

Each view of our mobile pages contain 3 basic blocks, a header (data-role="header"), a content (data-role="content"), and a footer (data-role="footer"), lines 39, 46, and 81 respectively. We also used data-theme in each block to change the look and feel of the page. Please see the data attributes reference for the complete list of data attributes supported by JQuery Mobile 1 here (JQuery Mobile Documentation).

The following uses multi page template with our About page (line 103) in the same XHTML document. A separate XHTML document may be created for single page templates.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>The Kahimyang Project Mobile

        <link href="./images/favicon.ico" rel="shortcut icon" 
               type="image/x-icon"/>

        <meta name="viewport" 
           content="width=device-width, initial-scale=1" />
        <link rel="stylesheet"
           href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
        <script type="text/javascript"
           src="http://code.jquery.com/jquery-1.6.4.min.js">

        </script>
        <script type="text/javascript"
            src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js">

        </script>

        <script src="./js/jquery.timeago.js" 
             type="text/javascript"></script>
        <script type="text/javascript">
            jQuery(document).ready(function() {
            jQuery("span.timeago").timeago();
        });
        </script>
    </h:head>

    <body>
        <div data-theme="b"  data-role="page" id="main">

            <div data-role="header">
                <div data-theme="a" data-role="content">
                    <h:outputText style="font-style: italic;"
                                  value="The Kahimyang Project Mobile" />
                </div>
            </div>

            <div data-theme="e" data-role="content">

                <ui:repeat value="#{kmBean.blogsList}" var="blog">
                    <h:panelGrid 
                        styleClass="left-text ui-corner-all ui-shadow"
                        style="padding:10px;margin-bottom: 15px;width:100%;">

                        <a style="font-weight: bold;text-decoration: none;"
                           href="/mobile/Blog.xhtml?id=#{blog.id}"
                           data-transition="flip" data-theme="b">
                            #{blog.title}
                        </a>

                        <!-- Removed for clarity -->


                        <h:outputText  escape="false"
                                 style="font-size: 11px;font-style: italic;"
                                 value="#{blog.first}" />


                        <a data-role="button"
                           data-transition="flip"
                           href="/mobile/Blog.xhtml?id=#{blog.id}"
                           data-inline="true"
                           data-theme="b"
                           data-iconpos="notext"
                           data-icon="arrow-r" >Continue reading</a>

                    </h:panelGrid>

                </ui:repeat>

            </div>

            <div data-position="fixed" data-role="footer">
                <div data-role="navbar" >
                    <ul>
                        <li>
                            <a href="/mobile/Search.xhtml"
                               rel="external" data-icon="search" >Search</a>
                        </li>
                        <li>
                            <a data-icon="grid" rel="external"
                               href="/mobile/Map.xhtml" >Locate Us</a>
                        </li>
                        <li>
                            <a data-icon="info"
                               data-rel="dialog"  href="#about" >About Us</a>
                        </li>
                    </ul>
                </div>
            </div>
        </div>

        <!-- About page -->

        <div data-theme="e" data-role="page" id="about">

            <div data-role="header">
                <p style="float:right;font-size: medium">About Us</p>
            </div>

            <div data-role="content">
                <h:panelGrid style="width:100%;padding:10px;"
                             styleClass="left-text ui-corner-all ui-shadow">

                    <p>
                        Contact us at kahimyang@gmail.com for 
                        any matters related to this site.
                    </p>

                </h:panelGrid>
            </div>

            <div data-role="footer">
                <p style="float:left;font-size: small;">
                    Copyright 2011,  The Kahimyang Project
                </p>
            </div>
        </div>
    </body>
</html>

rel="external" (and ajax="false") cause an anchor page to be refreshed and date-transition to "none". See line 86 in our home page.

The backing bean

Below is the backing bean of the page above. This is used primarily as the value of ui:repeat tag of our main content block.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.kahimyang.mobile;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;


@ManagedBean
@RequestScoped
public class KmBean {

    public KmBean() {
    }

    private List<Blogs> blogsList=null;

    public List<Blogs> getBlogsList() {

        if (blogsList != null) {
             return blogsList;
        }

        Database db = new Database();
        Connection conn = null;

        try {
            conn = db.dbconnect();
        } catch (Exception e) {

        }

        final String q = "query string";

        try (
                Statement stmt = conn.createStatement();
                ResultSet set = stmt.executeQuery(q)) {
            if (set.first()) {

                blogsList = new ArrayList<>();
                String id;
                String title;
                String link;
                while (!set.isAfterLast()) {
                     
                    // Some lines removed for clarity

                    Blogs b = new Blogs(id, title, f.format(D),F);
                    b.setTimeAgo(timeago);
                    blogsList.add(b);

                    set.next();
                }

            }

        } catch (Exception e) {

        }

        return blogsList;

    }

    public class Blogs {

        String id;
        String title;
        String date;
        String first;

        public Blogs(String id, String title, 
                      String date, String first) {
            this.id = id;
            this.title = title;
            this.date = date;
            this.first = first;
        }

        public String getId() {
            return id;
        }

        public void setId(String s) {
            id = s;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String s) {
            title = s;
        }

        public String getDate() {
            return date;
        }

        public void setDate(String s) {
            date = s;

        }

        public String getFirst () {
            return first;
        }


        public void setFirst (String s){
            first = s;
        }
    }

}

Our JSF/JQuery website uses the default configuration. Here is the configuration parameters if you want to change the default behaviour of your website.

*Below is a sample configuration that overrides touchOverflowEnabled to enable smoother page transitions and true fixed toolbars and defaultDialogTransition.

        <script type="text/javascript">
            $(document).bind("mobileinit", function(){
              $.extend(  $.mobile , {
                touchOverflowEnabled: true,
		defaultDialogTransition: 'slide'  
              });
            });  
        </script> 

*The configuration above is an update to our website on December 12, 2011 inserted in the head section just after the JQuery mobile include.

That's it. Good luck.


11,628

Comments (Building a mobile website with JSF 2 core and JQuery Mobile 1.0)