Este post forma parte de una serie de cuatro:
- Tutorial jQuery Mobile + Knockout (I): Sentando las bases
- Tutorial jQuery Mobile + Knockout (II): Creando las vistas con jQuery Mobile (esto que estás leyendo)
- Tutorial jQuery Mobile + Knockout (III): Definiendo el ViewModel con Knockout
- Tutorial jQuery Mobile + Knockout (y IV): Configurando el Data Binding
Creando las vistas con jQuery Mobile
Ahora que ya tenemos una idea de qué hacen jQuery Mobile y Knockout, llega el momento de presentar la aplicación de ejemplo que usaremos durante el tutorial.
La aplicación: W.I.Z.A.R&D
La aplicación que vamos a implementar se llama WIZARD (Weapon Inventory for Zombie Apocalypse Research & Development) y es una aplicación muy sencilla que nos ayuda a seleccionar las mejores armas para sobrevivir a un apocalipsis zombie. Su interfaz de usuario se compone de tres pantallas:

Pantallas de W.I.Z.A.R&D
La primera pantalla muestra una lista con las armas que tenemos seleccionadas para sobrevivir al apocalipsis zombie e incluye el peso total de nuestro inventario. Al pulsar sobre un arma se accederá al a segunda pantalla, donde podremos introducir los datos que hemos recogido de ese arma.
También podremos añadir nuevas armas pulsando sobre el botón Añadir, con lo que se mostrará un cuadro diálogo como el de la tercera pantalla. Por último, podremos eliminar armas pulsando sobre el botón de eliminar que aparece a la derecha de cada arma de la lista.
Queda claro con esto que los ejemplos de aplicaciones siguen sin ser lo mío, pero para jugar un poco con jQuery Mobile y Knockout nos puede servir.
Como vimos en la introducción del tutorial, para representar cada pantalla (vista en terminología MVVM) jQuery Mobile usa elementos div
con el atributo data-role="page"
. De momento vamos a centrarnos en cómo implementar cada pantalla con jQuery Mobile, sin emplear Knockout ni enganchar eventos de navegación para conocer mejor algunas características de jQuery Mobile.
La lista de armas
El código de la pantalla principal de W.I.Z.A.R&D es el siguiente:
<div data-role="page" id="home"> <div data-role="header"> <h1>W.I.Z.A.R&D</h1> <a href="#" data-role="button" data-icon="add" class="ui-btn-right">Añadir</a> </div> <div data-role="content"> <ul data-role="listview"> <li> <a href="#">Martillo</a> <a href="#" data-role="button" data-icon="delete" data-theme="d"></a> </li> <!-- Aquí irían el resto de armas --> </ul> </div> <div data-role="footer" data-position="fixed"> <h3>Peso Total: 3.45 kgs.</h3> </div> </div>
Cosas a tener en cuenta:
- La página queda contenida en un
div
con el atributodata-role="page"
. Elid
que asignamos aldiv
es importante porque será lo que nos permita identificar la página y navegar hasta ella. - Cada parte de la página tiene asignado su propio rol. Así tenemos la cabecera (
data-role="header"
), el contenido (data-role="content"
) y el pie (data-role="footer"
). - Para mostrar una lista de elementos existe el rol
listview
. jQuery Mobile es además lo bastante listo para formatearla para que quede bonita y colocar el icono de eliminar a la derecha. - Usando atributos
data-*
de HTML5 se pueden controlar más cosas, como la posición, el icono o incluso el tema.
Un factor a tener en cuenta es que toda la personalización que hace jQuery Mobile de los elementos html se realiza sólo al mostrar la página por primera vez, por lo que si añadimos dinámicamente nuevos elementos habrá que indicar a jQuery Mobile que reaplique la personalización. Veremos ejemplos de esto en la siguiente parte del tutorial.
Una cosa que resulta un poco confusa es que a veces para cambiar el aspecto o la posición de algo hay que usar atributos data-*
, como el data-position="fixed"
que aparece en el footer
, y otras veces se usan clases css, como el ui-btn-right
del botón de Añadir del header
.
Modificar un arma
jQuery Mobile permite mantener las distintas páginas, es decir los distintos div
s con el atributo data-role="page"
, en varios archivos y cargarlas a través de peticiones AJAX. Sin embargo, en este caso, y para mantener las cosas simples, todas las vamos a colocar en el mismo fichero html. El código correspondiente a la página de edición de un arma es éste:
<div data-role="page" id="edit"> <div data-role="header"> <a href="#" data-rel="back" data-role="button" data-icon="back" data-theme="a">Back</a> <h1>Martillo</h1> </div> <div data-role="content"> <div data-role="fieldcontain"> <div> <label for="weight">Peso</label> <input type="number" id="weight" value="1"/> </div> <div> <label for="ammoType">Munición</label> <select id="ammoType"> <option>Ilimitada</option> <option>Escasa</option> <option>Abundante</option> </select> </div> <div> <label for="closeCombatRating">Efectividad cuerpo a cuerpo</label> <div id="closeCombatRating">TODO</div> </div> <div> <label for="rangeRating">Efectividad a distancia</label> <div id="rangeRating">TODO</div> </div> </div> </div> </div>
No tiene mucho de especial. De momento con este código no se muestran las estrellitas para calificar el arma, eso lo haremos más adelante con Knockout.
Lo más reseñable es que para añadir un botón para volver a la página anterior sólo hay que añadir el atributo data-rel="back"
al enlace y jQuery Mobile se encargará de todo.
Añadir un nuevo arma
Este es un caso un poco especial porque esta vista queremos mostrarla como un diálogo en lugar de como una página normal. Para ello usamos el siguiente código:
<div data-role="dialog" id="addNew"> <div data-role="header"> <h1>Añadir Arma</h1> </div> <div data-role="content"> <label for="newWeaponName">Nombre:</label> <input type="text" name="newWeaponName"></input> <fieldset class="ui-grid-a"> <div class="ui-block-a"><a href="#" data-rel="back" data-role="button">Cancelar</a></div> <div class="ui-block-b"><a href="#" data-rel="back" data-role="button" data-theme="b">Aceptar</a></div> </fieldset> </div> </div>
Para crear el diálogo debemos marcar el div
con rol data-role="dialog"
. De esta forma jQuery Mobile lo tratará como diálogo y le dará otro aspecto. Se supone que el diálogo debe estar siempre en un fichero html distinto, pero lo cierto es que en este ejemplo está todo en el mismo fichero html y funciona correctamente.
En este caso estamos haciendo uso de clases css de jQuery Mobile para colocar los botones de Cancelar y Aceptar uno al lado del otro en lugar de uno encima de otro. Para ello se usa la siguiente estructura:
<fieldset class="ui-grid-a"> <div class="ui-block-a"><a href="#" data-rel="back" data-role="button">Cancelar</a></div> <div class="ui-block-b"><a href="#" data-rel="back" data-role="button" data-theme="b">Aceptar</a></div> </fieldset>
Al englobar ambos botones en un fieldset
con la clase ui-grid-a
jQuery Mobile monta un grid que nos permite colocarlos en línea.
Para apreciar la diferencia entre usar un data-role="dialog"
y un data-role="page"
, nada mejor que una captura de pantalla:
Por dónde seguimos
Lo que tenemos de momento no son más que unas cuantas páginas estáticas e inconexas entre las que ni siquiera podemos navegar. En la próxima parte del tutorial introduciremos Knockout en la aplicación para tener un ViewModel con el que interactuar y hacer la cosa un poco más interesante.
De todas formas, si quieres ver el código completo del tutorial lo puedes encontrar ya en su repositorio de github o acceder directamente a la demo online de W.I.Z.A.R&D.
Exelente el tutorial, esperando con ancias el tercero, gracias por compartir tus conocimientos. Saludos desde México.
Muchas gracias por el comentario, me alegro de que te guste. En un par de días estará lista la tercera parte.
Pingback: Tutorial jQuery Mobile + Knockout (I): Sentando las bases « Koalite's blog
Gracias por el tutorial.
Aún estoy entrando en esto del jquery mobile y html5 y me ha venido muy bien: muy limpio y con buenos ejemplos.
Así da gusto!
Un saludo
Que buen tutorial, bastante ilustrativo.