Skip to content
Slava P. edited this page May 20, 2015 · 21 revisions

Requirements

This page gives a quick start guide on how to use this project to bring together jQuery Mobile and GWT.

We will assume you are familiar with Java and GWT. You do not need to know Javascript because that is the aim of the GWT project (to abstract away Javascript).

We will further assume you have GWT setup on your system and a project already created.

More advanced examples are show in the tutorials area.

Project Setup

A jqm4gwt project is exactly like any other GWT project, but with a single added dependency.

Download the latest *.jar from the downloads area and then make them available on the classpath of your GWT project. In Eclipse you would add the jar to your libraries in the build path section.

If you are using maven with GWT you can add the jar as a dependency, jqm4gwt is available on Maven Central.

You have to choose how jquery and jqueryMobile scripts are injected. There are 3 possible options:

  1. Manually in your html file, then no jqm4gwt-standalone nor jqm4gwt-remote are needed.
  2. Copy from standalone, then jqm4gwt-standalone must be the first in java build path order, before jqm4gwt-library (and no jqm4gwt-remote is needed).
  3. Reference to remote hosts, then jqm4gwt-remote must be the first in build path order, before jqm4gwt-library (and no jqm4gwt-standalone is needed).

If Maven is used, then you just specify only ONE dependency: standalone OR remote OR library

<dependency>
  <artifactId>jqm4gwt-standalone</artifactId>
  <!-- artifactId>jqm4gwt-remote</artifactId-->
  <!-- artifactId>jqm4gwt-library</artifactId-->
  <version>${jqm4gwt.version}</version>
  <scope>provided</scope>
</dependency>

Also you can add optional plugins:

  • datebox - date picker with pretty look and feel.
  • grid960 - CSS grid system, kind of obsolete, because JQMTable has now percentage columns functionality.
  • iscroll - "native" scrolling, probably better results can be achieved with plain CSS by using:
-webkit-overflow-scrolling: touch;

see also predefined jqm4gwt-scrollable-main-stage CSS style.

Next, you update the gwt.xml file to inherit from jqm4gwt. You do this by adding the following line:

<inherits name='com.google.gwt.user.User' />

<inherits name='com.sksamuel.Jqm4gwt' />

<!-- Only if you use plugins, add corresponding line for each of used -->
<inherits name='com.sksamuel.Jqm4gwt-datebox' />
<inherits name='com.sksamuel.Jqm4gwt-grid960' />
<inherits name='com.sksamuel.Jqm4gwt-iscroll' />

That should be familiar as you will have other inherit statements in there as well.

You must update the page where you host the GWT generated Javascript file.

Only if you decided to include jQuery manually:

Include the jQuery and jQuery Mobile libraries by adding statements like the following to the head element of your HTML page:

<link rel="stylesheet" href="examples/css/jquery.mobile-1.4.5.min.css" />
<script src="examples/js/jquery-2.1.4.min.js"></script>
<script src="examples/js/jquery.mobile-1.4.5.min.js"></script>

As you can see, this is just linking to the libraries relative to examples application.

You can use jqm4gwt-standalone OR jqm4gwt-remote to include jQuery scripts automatically.

For all versions of jqm4gwt add the following:

Disable jQuery Mobile navigation location hash, it's not supported by jqm4gwt.
You can use Errai Navigation (see HistoryWrapper) or GWT PushState to support navigation in your application.

In case of jQuery manual inclusion (jqm4gwt-library in your pom.xml), you can use the following code:

<script src="js/jquery-2.1.4.min.js"></script>
    
<script type="text/javascript"> 
  // See http://www.gajotres.net/prevent-jquery-mobile-from-using-hash-navigation/
  $(document).on("mobileinit", function () {
    $.mobile.hashListeningEnabled = false;
    $.mobile.pushStateEnabled = false;
    $.mobile.changePage.defaults.changeHash = false;
  });
</script>

<script src="js/jquery.mobile-1.4.5.min.js"></script>

Otherwise you have to use obsolete and not very reliable method:

<script type="text/javascript">
  if (window.location.hash.length > 0) {
    window.location.hash = ' ';
    window.location = window.location;
  }
</script>

These little scripts remove the location hash. This is required to work around the fact the pages in jqm4gwt are dynamically generated, and if a user refreshes the page, the jQuery Mobile framework will attempt to load a page with the hash value. So we must remove any hash that is there before the pages are loaded. In the future we will look into a better solution.

Finally, in your body element you must add a div

<div data-role="page" id="start"></div>

This is because jQuery Mobile will give an error if there is not at least one page initially.

Also the following viewport declaration should be added to the head:

<meta name="viewport" content="width=device-width, minimal-ui, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

Your final page should resemble something like the following, where NAME_OF_GWT_MODULE is whatever your gwt.xml is called.

<!doctype html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- meta http-equiv="content-type" content="text/html; charset=UTF-8" -->
    
    <title>jqm4gwt Examples</title>
    <meta charset="utf-8">
        
    <meta name="viewport" content="width=device-width, minimal-ui, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    
    <!-- iPad related settings: https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- --------------------- -->

    <script type="text/javascript">
        if (window.location.hash.length > 0) {
          window.location.hash = ' ';
          window.location = window.location;
        }
    </script>
    
    <script type="text/javascript" src="NAME_OF_GWT_MODULE/NAME_OF_GWT_MODULE.nocache.js"></script>
  </head>
  <body>
    <div class="ui-loader-background"></div>
    <div data-role="page" id="start"></div>
  </body>
</html>

Hello World

Now that the project is setup, we can begin to build a jQuery Mobile page.

This is just like building a normal page but instead of using the normal GWT widgets, we will use the wrapped jQuery Mobile widgets.

Lets build a Hello World example.

In the jQuery Mobile universe each page is contained in its own

element. jQuery Mobile then parses those divs and injects the contents into the visible DOM.

Normally, outside of GWT, you would make these pages manually, perhaps one in each file. And then you would link between them using the button elements.

In jqm4gwt we use instead the JQMPage object. To this page object we then add the widgets we require, such as buttons, checkboxes, list views, etc. Just like building a normal GWT app, Swing app, whatever. you can think of the JQMPage object as like a GWT FlowPanel.

It is always easier to understand with a code example. Here is a Hello World page. You can see the rendered page on the examples page at http://jqm4gwt.appspot.com

	public class HelloWorldPage extends JQMPage {
	  public HelloWorldPage() {

	    add(new JQMHeader("Hello world header"));

	    add(new Paragraph("Hello world."));

	    add(new JQMFooter("Hello world footer"));
	  }
	}

How do we get to show a page? Well, when you instantiate a new JQMPage object, the page is automatically added to the DOM. Then when you want to show it in place of the current page, we can invoke a method called changePage on the JQMContext helper object.

HelloWorldPage page = new HelloWorldPage();
JQMContext.changePage(page);

And that's it, the page will be transitioned to show the hello world example.

Breaking change between 1.3.x and 1.4.x versions.

Since jqm4gwt version 1.4, you have to modify your application's entry point if jqm4gwt-standalone or jqm4gwt-remote is used for jQuery injection. That's caused by superdev mode support, and scripts cannot be injected through *.gwt.xml files anymore. So you have to explicitly wait till needed scripts are injected.

Entry point of application should look like this:

public class Jqm4gwtExamplesEntryPoint implements EntryPoint {
    /** This is the entry point method. */
    @Override
    public void onModuleLoad() {
        ScriptUtils.waitJqmLoaded(new Callback<Void, Throwable>() {

            @Override
            public void onSuccess(Void result) {
                runExamples();
            }

            @Override
            public void onFailure(Throwable reason) {
                Window.alert(reason.getMessage());
            }
        });
    }

    private static void runExamples() {
        JQMPage page = new JQMPage("examples");
        page.add(new JQMHeader("Examples"));
        page.add(new JQMFooter("jqm4gwt open source project"));
        JQMContext.changePage(page);
    }
}

Of course you don't always need to change page by calling changePage(page). In fact, you would not typically do that except to display the first page inside the onModuleLoad() in your entrypoint class.

Normally, you would transition pages by setting the page as the action on a button or a link. Something like the following.

SomeOtherPage page = new SomeOtherPage ();
JQMButton button = new JQMButton("click me to change page", page);

And then jqm4gwt will take care of making all the appropriate links.

Further reading

That's all for the quick start guide. It's really very simple to use, and all the widgets are what you would expect them to be called, except prefaced with JQM - e.g. JQMList, JQMSlider, JQMTextArea.

Clone this wiki locally