What Will I Learn?
Displaying windows with jQuery Mobile
Requirements
jQuery Mobile Framework https://jquerymobile.com/
Difficulty
Intermediate
Tutorial Contents
- A first window
- Pages and windows : define the terms used
- If you do not use windows?
- Move from one window to another
- Windows located in different HTML pages
- Keep the windows in memory with the data-dom-cache attribute
- Anticipating loading of windows with the data-prefetch attribute
- Use transitions between windows
- Dialog windows
- Using CSS themes
- Creating your own themes
jQuery Mobile Tutorial: Displaying windows
A first window
The first example consists first to display a HTML page in the browser, using the functionality of jQuery Mobile.
The first HTML page using jQuery Mobile
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page> <div data-role=header> <h1>Window title</h1> </div>
<div data-role=content> <p> Window content </p> </div></div>
</body></html>
Our HTML page includes a <div> element which data-role attribute has the "page" value. It corresponds to a window that will be displayed on the screen. So a window will be a <div> element that has a data-role attribute with the "page" value.
The window in our example has two main <div> elements. The first is the title bar of the application (header), and therefore has the data-role attribute set to "header". It used to contain the title of the window displayed, here included in an <h1>. The second is the specific content of the window, located below the title bar. It corresponds to a <div> element with the data-role attribute set to "content", and can contain any HTML elements that will be displayed in the window.
It is also possible to define a bar at the bottom of page. This bar is called footer. Noted in the HTML using the data-role="footer" attribute. For example:
A window with a header and footer
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page> <div data-role=header> <h1>Window title</h1> </div>
<div data-role=content> <p> Window content </p> </div>
<div data-role=footer> <h1>Window bottom</h1> </div></div>
</body></html>
A bar has appeared at the bottom of the page (after the contents of the page). To place the bottom bar at the bottom of the window, it is necessary that the contents of the window is more consistent, or that the <div> associated with the bar has the data-position="fixed" attribute. This will be discussed in the chapter on the toolbars.
Pages and windows : define the terms used
jQuery Mobile primarily uses the term page, eg when writing data-role="page". The page is the window on the screen. It should not be confused with the HTML page itself, which in fact may contain multiple windows (or jQuery Mobile pages as defined).
To avoid confusion, we use the term window when it comes to the display window (corresponding to <div> elements with the attribute data-role with the value "page"), and the term HTML page, when the HTML page including one or more windows. We will avoid using the term page used without further qualification, we believe too ambiguous.
And if you do not use windows?
jQuery Mobile predicted that you would use the window system without this having a window included in the HTML code as we have previously written. This facility allows you to not block the display if HTML is not written as expected.
Let's write a basic HTML page that does not contain <div> elements as described above:
An HTML page displayed as a window
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<p> Window content </p>
</body></html>
We omit <div> elements with data-role attributes set to "page", "header" or "content". Yet this HTML page is displayed as a window with jQuery Mobile transforming the original HTML code by surrounding it with a <div> element having the data-role = "page" attribute.
Move from one window to another
For now, our application has only one window, in fact one <div> element with the data-role="page" attribute. Let's write an HTML page with two <div> elements that have this feature.
An HTML page containing two windows
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win1> <div data-role=header> <h1>Window 1</h1> </div>
<div data-role=content> <p> Window content 1</p> <a href=#win2> Goto window 2 </a> </div></div>
<div data-role=page id=win2> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
Notice that we assigned an id attribute to <div> elements for the two windows. The first window contains a link to go to the second window, using the href="#win2" attribute, win2 is the id of this window. Check that it works:
Click on the link to access the second window:
The new window appears, but it can sometimes be useful to include a Back button to return automatically to the previous window. This button is normally displayed in the title bar of the new window, on its left side.
To do this, jQuery Mobile uses the data-add-back-btn attribute set to "true". This attribute must be set to the <div> corresponding to the window where the button will be displayed. We will therefore:
View the Back button in the second window
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win1> <div data-role=header> <h1>Window 1</h1> </div>
<div data-role=content> <p> Window content 1</p> <a href=#win2> Goto window 2 </a> </div></div>
<div data-role=page id=win2 data-add-back-btn=true> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
We now obtain:
Windows located in different HTML pages
The previous windows were all included in one file. The transition between the two windows is done without making a request to the server, since the two windows are present in memory when loading the HTML page (even if at a given time, only one window is visible on the display).
jQuery Mobile allows you to insert the windows in separate files. To load the second window, it performs an Ajax call to the server, to retrieve the window HTML code. This window is then inserted into the DOM tree and displayed.
File containing the first window (index.html)
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win1> <div data-role=header> <h1>Window 1</h1> </div>
<div data-role=content> <p> Window content 1</p> <a href=index2.html> Goto window 2 located in index2.html </a> </div></div>
</body></html>
File containing the second window (index2.html)
<!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html;charset=iso-8859-1 /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win2 data-add-back-btn=true> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
Keep the windows in memory with the data-dom-cache attribute
In the above example, note that if you navigate between the windows, the second window appears, causing the appearance of a waiting message(Loading). This means that jQuery Mobile queries the server through Ajax to retrieve the HTML of this window. The Ajax call is made before the display of the second window, and each time this window will be displayed. The reason is that the second window is removed from the DOM tree when it becomes hidden, this allows jQuery Mobile optimize memory space. An Ajax call is necessary to redisplay the window later, because the window was removed from memory.
It is possible to tell jQuery Mobile to make the loading of the window only once (the first), then keep the window always in the DOM tree. A single Ajax call will be made (the first), allowing faster display of the second window in the following views. This is done using the data-dom-cache="true" attribute positioned on the window that is to be kept in memory.
The second window can then be written as follows (the code of the first window is not changed):
Keep in memory the window with the data-dom-cache="true" attribute (index2.html file)
<!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html;charset=iso-8859-1 /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win2 data-add-back-btn=true data-dom-cache=true> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
Note that the data-dom-cache attribute is only used for windows in external files, ie retrieved by Ajax. When both windows are located in the same HTML file, no Ajax call is made by jQuery Mobile, so the windows remain in memory in all cases.
Anticipating loading of windows with the data-prefetch attribute
Using the previous example for the two windows in different files. It is possible to load the second window in the background, without waiting to have clicked on the link to view it. Simply specify the data-prefetch attribute (no associated value) in the <a> link containing the reference to that window. Loading the first window (the one containing the link), jQuery Mobile searches of all the links containing the data-prefetch attribute and load windows in the background. These windows will be immediately available when the associated link is clicked.
The two windows are then written:
HTML code for the first window
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win1> <div data-role=header> <h1>Window 1</h1> </div>
<div data-role=content> <p> Window content 1</p> <a href=index2.html data-prefetch> Goto window 2 located in index2.html </a> </div></div>
</body></html>
The use of the data-prefetch attribute automatically load the window in index2.html without waiting for the link is clicked.
HTML code for the second window (automatically loaded in memory when displaying the first window)
<!DOCTYPE html> <html> <head> <meta http-equiv=Content-Type content=text/html;charset=iso-8859-1 /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win2 data-add-back-btn=true> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
Now we find that clicking on the link that shows the second window no longer causes the waiting message (Loading). The second window is displayed directly as soon as the link is clicked.
Use transitions between windows
The transition between the two windows is done for the moment by a shift from right to left, the second pushing the first window to the left as and when it occurs. jQuery Mobile can change the effect in the transition between the two windows.
Use such as a flip transition between the two windows. Simply add the data-transition="flip" attribute in the HTML of the link to the second window:
Use a flip transition between the two windows
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win1> <div data-role=header> <h1>Window 1</h1> </div>
<div data-role=content> <p> Window content 1</p> <a href=#win2 data-transition=flip> Goto window 2 </a> </div></div>
<div data-role=page id=win2 data-add-back-btn=true> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
When clicking on the link to proceed to the second window, the transition between the two windows is now done by an effect of horizontal rotation between the two windows. When pressing the Back button, the transition has the same effect, but in an opposite direction.
Dialog windows
Previous transitions can move from one window to another. The second window replaces the previous display. Return to the previous window can be done by the Back button located in the title bar.
jQuery Mobile has provided the ability to display a window above the other, instead of replacing it on the screen. It has overlapping windows, such as a dialog box that appears over a window display.
Two ways are offered by jQuery Mobile:
- Either one indicates in the attribute of the link, it is desired to open a new window, which will be superimposed on the previous,
- Either one indicates in the attributes of the new window, it's an overlay (a dialog), and each viewing of this window will display it as such.
We examine below these two possibilities.
The dialog window is defined by the attributes of the link
This is the first way to create a dialog window. To create it (instead of a single window), simply indicate in the link, the data-rel="dialog" attribute. Clicking the link opens a new window (as for all links), but this window will be superimposed over the previous one, without making it disappear.
Display a dialog window with the attribute of the link
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win1> <div data-role=header> <h1>Window 1</h1> </div>
<div data-role=content> <p> Window content 1</p> <a href=#win2 data-rel=dialog data-transition=pop> Goto window 2 </a> </div></div>
<div data-role=page id=win2> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
By clicking the link in the first window, the second window appears:
jQuery Mobile automatically added in the title bar of the dialog window, a close button symbolized by a cross. Clicking on this button to close this window and return to the previous window (below it).
It is possible to insert ourselves a close button in the window contents. You just have to simulate the Back button.
The dialog window is defined by its attributes
Rather than indicating in the link that you want to open a dialog window, it indicates in the attributes of the window it is a layered window. The opening of this window always take place over the previous one.
For this is indicated in the attributes of the window data-role="dialog" (instead of data-role="page"). The previous example becomes:
Display a layered window with the attribute of the window
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win1> <div data-role=header> <h1>Window 1</h1> </div>
<div data-role=content> <p> Window content 1</p> <a href=#win2 data-transition=pop> Goto window 2 </a> </div></div>
<div data-role=dialog id=win2 data-add-back-btn=true> <div data-role=header> <h1>Window 2</h1> </div>
<div data-role=content> <p> Window content 2</p> </div></div>
</body></html>
The result is the same as the previous example.
Using CSS themes
jQuery Mobile allows you to use different styles for each window used in HTML pages. By default, a style is applied to them, but it is very easy to use another one.CSS styles defined by jQuery Mobile correspond to the letters a, b, cd and e. These styles are defined in the file jquery.mobile.css, in the file header. Here is an extract file for style definitions associated with the theme "a":
Definitions of the theme "a" in the file jquery.mobile.css
/* A -----------------------------------------------------------------------------*/
.ui-bar-a {
border: 1px solid #2A2A2A;
background: #111111;
color: #ffffff;
font-weight: bold;
text-shadow: 0 -1px 1px #000000;
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#111));
background-image: -webkit-linear-gradient(top, #3c3c3c, #111); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient(top, #3c3c3c, #111); /* FF3.6 */
background-image: -ms-linear-gradient(top, #3c3c3c, #111); /* IE10 */
background-image: -o-linear-gradient(top, #3c3c3c, #111); /* Opera 11.10+ */
background-image: linear-gradient(top, #3c3c3c, #111);
}
.ui-bar-a,
.ui-bar-a input,
.ui-bar-a select,
.ui-bar-a textarea,
.ui-bar-a button {
font-family: Helvetica, Arial, sans-serif;
}
.ui-bar-a .ui-link-inherit {
color: #fff;
}
.ui-bar-a .ui-link {
color: #7cc4e7;
font-weight: bold;
}
.ui-body-a {
border: 1px solid #2A2A2A;
background: #222222;
color: #fff;
text-shadow: 0 1px 0 #000;
font-weight: normal;
background-image: -webkit-gradient(linear, left top, left bottom, from(#666), to(#222));
background-image: -webkit-linear-gradient(top, #666, #222); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient(top, #666, #222); /* FF3.6 */
background-image: -ms-linear-gradient(top, #666, #222); /* IE10 */
background-image: -o-linear-gradient(top, #666, #222); /* Opera 11.10+ */
background-image: linear-gradient(top, #666, #222);
}
.ui-body-a,
.ui-body-a input,
.ui-body-a select,
.ui-body-a textarea,
.ui-body-a button {
font-family: Helvetica, Arial, sans-serif;
}
.ui-body-a .ui-link-inherit {
color: #fff;
}
.ui-body-a .ui-link {
color: #2489CE;
font-weight: bold;
}
.ui-br {
border-bottom: rgb(130,130,130);
border-bottom: rgba(130,130,130,.3);
border-bottom-width: 1px;
border-bottom-style: solid;
}
.ui-btn-up-a {
border: 1px solid #222;
background: #333333;
font-weight: bold;
color: #fff;
text-shadow: 0 -1px 1px #000;
background-image: -webkit-gradient(linear, left top, left bottom, from(#555), to(#333));
background-image: -webkit-linear-gradient(top, #555, #333); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient(top, #555, #333); /* FF3.6 */
background-image: -ms-linear-gradient(top, #555, #333); /* IE10 */
background-image: -o-linear-gradient(top, #555, #333); /* Opera 11.10+ */
background-image: linear-gradient(top, #555, #333);
}
.ui-btn-up-a a.ui-link-inherit {
color: #fff;
}
.ui-btn-hover-a {
border: 1px solid #000;
background: #444444;
font-weight: bold;
color: #fff;
text-shadow: 0 -1px 1px #000;
background-image: -webkit-gradient(linear, left top, left bottom, from(#666), to(#444));
background-image: -webkit-linear-gradient(top, #666, #444); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient(top, #666, #444); /* FF3.6 */
background-image: -ms-linear-gradient(top, #666, #444); /* IE10 */
background-image: -o-linear-gradient(top, #666, #444); /* Opera 11.10+ */
background-image: linear-gradient(top, #666, #444);
}
.ui-btn-hover-a a.ui-link-inherit {
color: #fff;
}
.ui-btn-down-a {
border: 1px solid #000;
background: #3d3d3d;
font-weight: bold;
color: #fff;
text-shadow: 0 -1px 1px #000;
background-image: -webkit-gradient(linear, left top, left bottom, from(#333), to(#5a5a5a));
background-image: -webkit-linear-gradient(top, #333, #5a5a5a); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient(top, #333, #5a5a5a); /* FF3.6 */
background-image: -ms-linear-gradient(top, #333, #5a5a5a); /* IE10 */
background-image: -o-linear-gradient(top, #333, #5a5a5a); /* Opera 11.10+ */
background-image: linear-gradient(top, #333, #5a5a5a);
}
.ui-btn-down-a a.ui-link-inherit {
color: #fff;
}
.ui-btn-up-a,
.ui-btn-hover-a,
.ui-btn-down-a {
font-family: Helvetica, Arial, sans-serif;
text-decoration: none;
}
The "ui-bar-a" CSS class defined for example the style of the title bar in the theme "a", while "ui-body-a" defined the style of window contents in this same theme. Other CSS classes used allow to style every element of the HTML page, as this theme (mainly the various button states: up, down, hover).
Set a new theme for a window
jQuery Mobile allows you to associate an independent theme for each component of the window (title bar, footer bar and contents of the window). It provides the data-theme, data-header-theme,data-footer-theme and data-content-theme attributes. Each of these attributes can have one of the themes defined by jQuery Mobile ("a", "b", ... "e") or theme defined by our application. As the theme of an element of the window can be defined in several places (eg the theme of the title bar can be defined by the data-theme attribute used on it or the data-header-theme attribute used on the window), jQuery Mobile has established a priority order for consideration of the final theme.
For the title bar (header), the following attributes are considered in order of decreasing priority:
- data-theme attribute set to the title bar,
- data-header-theme attribute set to the window. If this attribute is not defined in the HTML, default is "a".
- data-theme attribute set to the window. If this attribute is not defined in the HTML, default is "c". So that the value of this attribute is taken into account, we need the data-header-theme attribute set to "".
For the bottom bar (footer), the following attributes are considered in order of decreasing priority:
- data-theme attribute set to the footer bar,
- data-footer-theme attribute set to the window. If this attribute is not defined in the HTML, default is "a".
- data-theme attribute set to the window. If this attribute is not defined in the HTML, default is "c". So that the value of this attribute is taken into account, we need the data-footer-theme attribute set to "".
For the window content (content), the following attributes are considered in order of decreasing priority:
- data-theme attribute set to the window content,
- data-theme attribute set to the window. If this attribute is not defined in the HTML, default is "c".
- data-content-theme attribute set to window. Default is "".
We note that the data-theme attribute set to an element of the window has priority over other attributes defined on the other elements. The data-theme attribute will be that we mainly use.
To see the impact of the use of this attribute in our HTML pages, define a few windows each using one of the themes, and merging with each other via a <a> link in each of these.
Use a different theme in each window
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script></head>
<body>
<div data-role=page id=win> <!-- Default theme --> <div data-role=header> <h1>Default theme</h1> </div>
<div data-role=content> <p> Window content</p> <a href=#wina> Goto "a" theme </a> </div></div>
<div data-role=page id=wina data-add-back-btn=true> <div data-role=header data-theme=a> <h1> "a" theme </h1> </div>
<div data-role=content data-theme=a> <p> Window content</p> <a href=#winb> Goto "b" theme </a> </div></div>
<div data-role=page id=winb data-add-back-btn=true> <div data-role=header data-theme=b> <h1> "b" theme </h1> </div>
<div data-role=content data-theme=b> <p> Window content</p> <a href=#winc> Goto "c" theme </a> </div></div>
<div data-role=page id=winc data-add-back-btn=true> <div data-role=header data-theme=c> <h1> "c" theme </h1> </div>
<div data-role=content data-theme=c> <p> Window content</p> <a href=#wind> Goto "d" theme </a> </div></div>
<div data-role=page id=wind data-add-back-btn=true> <div data-role=header data-theme=d> <h1> "d" theme </h1> </div>
<div data-role=content data-theme=d> <p> Window content</p> <a href=#wine> Goto "e" theme </a> </div></div>
<div data-role=page id=wine data-add-back-btn=true> <div data-role=header data-theme=e> <h1> "e" theme </h1> </div>
<div data-role=content data-theme=e> <p> Window content</p> <p> End of themes</p> </div></div>
</body></html>
Display each window of the HTML page to view the corresponding themes:
Creating your own themes
jQuery Mobile has created an application that allows users to create their own themes. It is accessible on the URL http://jquerymobile.com/themeroller. It allows to create new themes for you by building a CSS theme file corresponding to the choices you made in the application. This file must then be included in your HTML page.
However, by following the conventions for writing jQuery Mobile CSS, we can write our own themes. For example write the "z" theme (non-existent to date).
Creating and using the "z" theme
<!DOCTYPE html> <html> <head> <meta name=viewport content="user-scalable=no,width=device-width" /> <link rel=stylesheet href=jquery.mobile/jquery.mobile.css /> <script src=jquery.js></script> <script src=jquery.mobile/jquery.mobile.js></script> <style type=text/css> .ui-bar-z { color : red; background-color : gainsboro; } .ui-body-z { font-style : italic; font-family : comic sans MS; } </style></head>
<body>
<div data-role=page id=win> <div data-role=header data-theme=z> <h1>"z" theme</h1> </div>
<div data-role=content data-theme=z> <p> New "z" theme is used in this window!</p> </div></div>
</body></html>
Here we define the theme of "z" in a rudimentary way, setting only the appearance of the title bar and window contents, using CSS classes respectively ui-bar-z and ui-body-z. The window will now look like this:
Posted on Utopian.io - Rewarding Open Source Contributors