Mostrando entradas con la etiqueta programacion. Mostrar todas las entradas
Mostrando entradas con la etiqueta programacion. Mostrar todas las entradas

Clases Abstractas e Interfaces.


Hablar de Herencia y Polimorfismo es desgastante, debido a que hay muchas cosas que explicar, así que para darme tiempo de terminar el post "Herencia y Polimorfismo, parte II" hablare acerca de clases abstractas e interfaces, que son parte importante de la Herencia y el Polimorfismo y son más sencillos de explicar.

Herencia y Polimorfismo, parte I.


Me había decidido a escribir sobre patrones de diseño ya que es un tema que actualmente estoy estudiando, sin embargo una de las primeras cosas que aprendí con los patrones de diseño es a favorecer la composición (HAS A) sobre la herencia (IS A), con lo cual quizás si no se conoce lo suficiente se subestime el poder de la herencia, así que lo mejor será comenzar con los principios básicos de programación, aunque por el momento solo tengo planeado abarcar la herencia y el polimorfismo.

La pila, el montículo y las variables de referencia (The stack, the heap and the reference variables)

A pesar de tener años programando este era uno de los temas que no lograba comprender al cien por ciento, después de investigar un poco entendí que lo desconocía incluso más de lo que pensaba, ya que aunque realmente sea un tema muy "simple" y pareciera al principio no muy crítico (debido quizás al Garbage Collector), resulta necesario conocerlo para comprender como se comporta nuestro programa en memoria, y para conocer cómo resolver conscientemente esos frustrantes errores de "StackOverFlowException" y "HeapOverFlowException" (java.lang.OutOfMemoryError en este caso), cabe mencionar que los temas abarcados aquí están enfocados a Java, aunque también pueden aplicar a otros lenguajes.

La pila y el montículo (The Stack and the Heap)

Primero que nada debemos conocer que existen dos espacios en donde se ejecutan nuestras aplicaciones, uno de ellos es la pila (Stack), en ella se guardan las variables locales y los métodos en ejecución, el otro es el montículo (Heap), en el se guardan las variables de instancia y los objetos. Cada Hilo (Thread) de la aplicación tiene su propia pila (Stack) pero todos comparten el mismo montículo (Heap), las variables y métodos de la pila (Stack) son eliminados al terminar su ejecución, las variables y objetos del montículo (Heap) son eliminados al no tener ninguna referencia hacia ellos y a capricho del Garbage Collector (al menos en Java y C#, aquí los gurús de C aplican el clásico "Ha Ha" con voz del Nelson), primero nos enfocaremos en la pila (Stack).

La pila (Stack)

Quizás una de las preguntas existenciales más difíciles es ¿De cuánto espacio dispone la pila (Stack)?, y la respuesta es un rotundo depende, incluso entre las mismas versiones de JVM (Java Virtual Machine) en distintas maquinas depende, y su explicación y configuración da para otra publicación más (insertar link cuando se tenga) por lo cual no trataremos aquí a fondo ese tema y solo te diremos que depende de la JVM, el sistema operativo, la configuración y el hardware, la siguiente pregunta a resolver sería ¿Cómo funciona la pila?, lo cual explicaremos a grandes rasgos, pero primero necesitamos un pequeño código para la explicación.

public class Program
{
                static int sumNNumbers(int n)
                {
                               if (n == 1)
                               {
                                               return 1;
                               }
                               else
                               {
                                               return n + sumNNumbers(n - 1);
                               }
                }
               
                public static void main(String[] args)
                {
                               System.out.println("Sum of the first 5 numbers: " + sumNNumbers(5));
                }
}

La pila (Stack) funciona como su homónima estructura de datos pila, el último elemento en llegar es el primero en salir (Last In First Out, LIFO), su comportamiento es parecido a una pila de objetos, por ejemplo una pila de platos si queremos añadir un nuevo plato a la pila lo ponemos en la cima, cuando queremos retirar un plato tomamos también el de encima.

Lo mismo sucede en la pila (Stack), y en cada llamada se almacena lo siguiente:

·         La dirección a la que se debe retornar después de la llamada.
·         Los datos pasados como parámetros de la llamada.
·         Las variables locales utilizadas por la función llamada.
·         Los datos devueltos, si la función los devuelve.

Si ejecutamos el código arriba expuesto, a grandes rasgos la pila se comportaría de esta manera:

·         El método main es puesto en la pila (Stack), con la variable args como parámetro.
·         El método println es puesto en la pila (Stack), con la dirección a la cual debe retornar después de su llamada y con su parámetro que es un String.
·         El método sumNNumbers es puesto en la pila (Stack), con la dirección a la cual debe retornar y con un entero como parámetro.
·         El método sumNNumbers es llamado recursivamente, puesto en la pila (Stack) n veces, con todos sus datos (dirección retorno, parámetros).
·         Una vez que llega a su último llamado, este es puesto en la pila (Stack), con la dirección a la cual debe retornar, un entero como parámetro, y al terminar su ejecución su valor de retorno, después regresa a su línea de retorno, devuelve el resultado y finalmente elimina sus variables y parámetros de la pila (Stack).
·         Se insertan uno por uno los valores de retorno del método sumNNumbers, y también se eliminan uno por uno sus datos de la pila (Stack) según se entreguen resultados.
·         Se retorna a la función println imprime el resultado en pantalla, una vez terminada su ejecución elimina sus datos de la pila (Stack) y regresa el método main.
·         El método main termina su ejecución y elimina sus datos del Stack.

Internamente su comportamiento es más complejo pero para fines didácticos nos basta, la tercera pregunta sería ¿Por qué se genera un StackOverFlowException? Esto es debido a que el espacio de la pila (Stack) es limitado, y cuando algún método quiere insertar sus datos en la pila (Stack)  y no se tiene espacio suficiente se genera esta excepción. Un ejemplo sería un método que se llama recursivamente de manera infinita ó en C# una propiedad que se auto asigne.

El montículo (Heap)

Otra pregunta difícil es ¿De cuánto espacio dispone el montículo (Heap)? Al igual que la pila (Stack) depende de la JVM, el sistema operativo, la configuración y el hardware, y ¿Cómo funciona el montículo (Heap)? Es un espacio donde se guardan variables de instancia y objetos (recuerda que es Java), que en lenguajes como Java y C# no pueden ser eliminados directamente sino con el Garbage Collector, y en lenguajes como C deben ser eliminados explícitamente (free), en este caso nos enfocaremos en Java y un poco en el Garbage Collector.

Después de este mini examen (espero haber aprobado) vamos directo al tema que es responder completamente la última pregunta. Los datos guardados en el montículo (Heap) son las variables de instancia y los objetos, pero ¿Qué es una variable de instancia? Son simplemente las propiedades expuestas de los objetos (instancias), para ejemplificarlo crearemos una clase llamada Car

class Stereo
{
                public void turnOn()
                {
                               System.out.println("Really cool music!!!");
                }
}

public class Car
{
                String carModel; // Instance Variable
                int carYear; // Instance Variable
                Stereo carStereo; // Instance Variable
               
                public static void main(String[] args)
                {
                               Car car;
                               car = new Car();
                               car.carModel = "Sentra";
                               car.carYear = 2005;
                               car.carStereo = new Stereo();
                               car.turnOnStereo();
                }
               
                void turnOnStereo()
                {
                               this.carStereo.turnOn();
                }
}

En este ejemplo las variables de instancia son carModel, carYear y carStereo, quizás en estos momentos piensas ¡¡Oye carStereo es un objeto también!! Pero carStereo no es un objeto sino una variable de referencia, ¿Qué es una variable de referencia?... Se explicara más adelante.

Volviendo al montículo (Heap), los objetos también son guardados en el mismo, en el código de Car hemos creado dos objetos, un objeto Car y un objeto Stereo y la instrucción que reservo la memoria, creo los objetos y regreso las referencias de los objetos es new, y ¿Cómo eliminamos los objetos? Eliminando todas las referencias hacia ese objeto, es decir eliminando las variables de referencia ó apuntando estas a otros objetos, aunque esto no los elimina los hace elegibles por el Garbage Collector quien finalmente es el encargado de eliminarlos.

Por último ¿Por qué se genera un java.lang. OutOfMemoryError? Al igual que la pila (Stack) el montículo (Heap) también es limitado, el JVM se asegura a través del Garbage Collector de tener la mayor cantidad de memoria disponible, cuando el Garbage Collector no puede recuperar suficiente memoria para la creación de un nuevo objeto se generá este error.

Variables de Referencia (Reference Variables)

Las variables de referencia, son tipos de datos especiales que guardan la referencia al objeto, el tipo de objeto y datos acerca de como acceder a los atributos y métodos del mismo, aunque es muy común en Java decir que los objetos se pasan por referencia en realidad no es exactamente así, lo que realmente sucede es que se hace una copia de una variable de referencia a otra, es decir se copian los bits de una variable a otra y como ambas hacen referencia al mismo objeto pareciera que se ha pasado el objeto por referencia, el código de abajo ejemplifica esta situación.

public class Cat
{
                String catName;
               
                public static void main(String[] args)
                {
                               Cat cat = new Cat();
                               cat.Name = "Meow";
                               System.out.println(cat.Name); // Imprime Meow
                               setCatName(cat);
                               System.out.println(cat.Name); // Imprime Meow
                }
               
                static void setCatName(Cat cat)
                {
                               cat = new Cat();
                               cat.Name = "Presley";
                               System.out.println(cat.Name); // Imprime Presley
                }
}

En el método main se crea un objeto Cat que es referenciado a través de la variable de referencia cat, y se le asigna el nombre "Meow" y se imprime, después se pasa como parámetro esta variable de referencia para el método estático setCatName, dentro de este se crea un nuevo objeto y se asigna a la variable de referencia que había sido pasada como parámetro, se le da el nombre "Presley" y se imprime, al regresar al método principal y volver a imprimir se muestra la cadena Meow, ¿Por qué no se imprimió Presley?, esto es debido a que al utilizar la instrucción new se creó un nuevo objeto y se referencio en la variable de referencia pasada como parámetro, a partir de ese momento las dos variables dejaron de referenciar al mismo objeto por lo que los cambios realizados en SetCatName no afectaron a la objeto original cat.

Tips SQLeros: Evitar Mostrar Errores en PHP

Generalmente cuando estamos en fase de producción nos gusta ver los errores que salen. pero cuando ya hemos acabado queda muy mal que el usuario final vea algún reporte de error en la web.

Colocando esta simple línea de código nos evitamos que s vean los errores:

error_reporting(0);


Lo ideal, claro está, sería que nuestro código tuviera un buen manejo de los errores. Pero muchas veces se requieren las cosas con tanto prisa que nos resulta imposible programar las excepciones.

Tip SQLero: net2ftp - Conectate a tu servidor FTP desde cualquier lugar



En ocasiones necesitamos darle un vistazo rápido al código fuente de alguna página que estemos desarrollando o simplemente necesitamos editar, borrar, actualizar un archivo.


Pero no siempre contamos con alguna red en la que podamos usar el ftp. O para colmo de males necesitamos hacer el cambio y estamos en la calle, o no tenemos nuestro equipo de computo a la mano, y solo contamos con un móvil o una tableta.


Hay una página que tiene ya algo de tiempo en la red que nos ayuda en estos casos de <<Urgencia>> y esta es net2ftp.






Esta aplicación nos ofrece muchas posibilidades como las que se enlistan a continuación:


Para usuarios

  • Navegar en el servidor FTP
  • Descargar archivos
  • Comprimir/Descomprimir archivos
  • Instalar software
  • Copiar/Mover y Eliminar
  • Copiar o Mover a otro servidor FTP
  • Renombrar y chmod
  • Ver archivos con resaltado de sintaxis.
  • Editor de texto plano
  • Editores HTML WYSIWYG
  • Editores de código
  • Buscar palabras o frases
  • Calculo de tamaño de archivos

Para Admins

  • Safe Mode
  • BD MySQL
  • Autorizaciones
  • Logging
  • Cuota/limite diario
  • Cuota/limite para archivos grandes
  • Plantillas
  • Calculo de tamaño de archivos
Es importante mencionar que esta aplicación web también tiene su interface móvil, espero que les sea de ayuda.

Más adelante iré publicando herramientas que hacen la vida más fácil a los desarrolladores. 

Un Saludo!

Eliminar un elemento en un array en PHP

Supongamos que tenemos un array en PHP como el siguiente:

$arr = array(
            1 => 'uno',
            2 => 'dos', 
            3 => 'tres', 
  );

Buscando alguna función para eliminar un elemento de $arr me topé con unset(), la cual para eliminar, por ejemplo, el segundo item se usaría de la siguiente manera:

unset($arr[2]);

Misión cumplida, o al menos eso uno espera, pero la sorpresa viene al observar el array resultante, el cual queda de la forma:


array(
            1 => 'uno',
            3 => 'tres',
  );

Desapareció el índice 2, lo que nos puede generar todo tipo de dolores de cabeza si trabajamos con los índices. Afortunadamente existe la función array_values() que hace una reasignación de índices para los elementos del array por nosotros. En nuestro caso se invoca:

$arr = array_values($arr);

Quedando $arr como


array(
            1 => 'uno',
            2 => 'tres',
  );

Para seguir trabajando normalmente.

Adrian Hands, el impresionante ejemplo de un programador que usaba el Morse para escribir código


Adrian Hands usando su dispositivo de escritura de código mediante MorseAdrian Hands usando su dispositivo de escritura de código mediante Morse

Para muchos, colaborar con el Software Libre es un gesto de altruismo: dedicas tu tiempo libre a realizar un trabajo no remunerado y probablemente nada sencillo sólo para que otros puedan disfrutar de nuevas funcionalidades en su PC o en su móvil. Vía Espacio Linux he conocido la historia de un programador que llevó más allá el concepto de altruismo.
Adrian Hands era un programador y aficionado al ciclismo estadounidense, al que en 2005 le diagnosticaron Esclerosis Lateral Amiotrófica (ELA, enfermedad de Lou Gehrig o mal de Charcot), unaenfermedad neurodegenerativa muy agresiva que va paralizando progresivamente los músculos hasta producir la muerte. A pesar de ello, Adrian siguió pedaleando, ya con una bicicleta reclinable, hasta 2007, y colaboró con el Software Libre hasta cuatro días antes de morir, el 3 de febrero de 2010.
Lo más increíble es cómo se las tuvo que arreglar para programar tras haber perdido la fuerza en los brazos por culpa de la ELA. Mediante un dispositivo llamado Darci USB (en honor a Darci, una niña sin manos para la que se construyó en primera instancia), Adrian consiguió comunicarse con su ordenador y dictarle en Morse el código que quería programar.
Darci USB, el dispositivo utilizado por AdrianDarci USB, el dispositivo utilizado por Adrian

No fue una tarea fácil en absoluto: además de regular la sensibilidad y la posición del mando para que Adrian pudiese utilizarlo correctamente, cuando la parálisis aumentó y no tenía fuerza suficiente para usar sus brazos, su hijo Ian le construyó una caja con interruptores para poder usarlo con sus piernas.
Así, el 30 de enero de 2010, Adrian consiguió enviar un interesante parche para Gnome, que permitía copiar al portapapeles bien una imagen o bien su ruta desde el menú contextual:
Created an attachment (id=177268) mod to add 2 new menu items: copy image (to clipboard) and copy path. added both to both the Edit menu and the right-click menu.
El parche fue aceptado y cinco días más tarde su hijo Ian escribió en el hilo del parche para agradecer la acogida a la comunidad de Gnome y para informarles de que su padre acababa de fallecer en India, donde recibía tratamiento para paliar la ELA.
Además, Ian compartió con la comunidad la foto de su padre programando que preside este artículo, y el último e-mail que le envió para compartir con su hijo la alegría por haber podido colaborar:
> ACCEPTed
> COMMITed
> RESOLVEd
> BOO-YAH!
>
> commit 0b209b1ff16e863e60a1d86413aa57c5fbde76b0
> Author: Adrian Hands 
> Date:   Fri Dec 31 14:34:58 2010 +0100
>
>    Add Copy Image and Copy Path to clipboard functionality
>
>    Fixes bug 78514.
>
>  data/eog-ui.xml  |    9 +++++++
>  src/eog-window.c |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 72 insertions(+), 0 deletions(-)
El esfuerzo de Adrian Hands fue una prueba infalible de que lo que a veces puede parecernos una tontería, para otros supone un mundo; y que en lugar de menospreciar el Software Libre por no tener tal o cual funcionalidad, deberíamos agradecer a la gente que ha dedicado su tiempo para desarrollar todas las funcionalidades que sí que tiene.
Así, en la edición de 2010 de los Free Software Awards, Richard Stallman y el resto de la FSF hicieron un reconocimiento a la labor de Hands, por su dedicación en servicio de la comunidad incluso en las más difíciles circunstancias. Reconocimiento que desde SQLeros queremos secundar para difundir la historia de este entusiasta de la programación y de la vida.
Vía | Espacio Linux
Blog de Adrian Hands | blog.ahands.org
Última colaboración de Adrian para Gnome | bugzilla.gnome.org
Dispositivo Morse utilizado | Darci USB
Imagen principal | Álbum de Adrian Hands en Picassa

Usar COM Interop Office (Excel) en tus proyectos ASP.NET y no morir en el intento...


En el proyecto en el que me encuentro, tenemos desarrollada una librería .NET para obtener informes en Excel mediante la llamada a una BAPI de SAP. Esta librería trabaja con el objeto COM de Excel y al mismo tiempo es consumida desde ASP.NET, sí, ya se que Microsoft no recomienda el uso de componentes Office en aplicaciones ASP.NET, "COM Interop with Microsoft Office products from an ASP.NET web page. Excel was not designed to be used inthis way" pero esto es un caso de fuerza mayor y no hay mas narices, puesto que son informes bastantes complejos que no basta con utilizar un DataGrid y rendereizar su contenido y lanzar una salida con Response.Write y poner el Response.ContentType = "application/vnd.ms-excel, como tantos ejemplos hay por ahí.
El problema con el que me he encontrado es el siguiente:
Todas las pruebas realizadas han funcionado a la perfección en las máquinas de desarrollo (Eso de ser Administrador de máquina...) pero... cuando lo he montado en el servidor de pruebas y he hecho la primera petición de un informe me he encontrado con esto:
Acceso Denegado
Juer, pues si que empezamos bien. La primera conclusión es evidente: Falta de Permisos, así que le he arrancado el Debugger de mi máquina y le he pedido a mi compañero que hiciera una petición de informe para ver donde casca:
ApplicationClass objExcel = new ApplicationClass();
Le he dado permisos de Administrador a mi compañero en mi máquina, ha vuelto a ejecutar la petición y ¡Vualá! todo funciona, porque estas llamadas a objetos COM necesitan para ejecución local/remota unos privilegios mínimos.
La configuración del sitio web tiene el acceso anónimo deshabilitado y la autenticación windows integrada (Estamos en una intranet) y en el Web.Config impersonate a true con autenticación Windows.
Soluciones que no piensas:
  • Dar permisos de Adminsitrador a la cuenta MACHINE\ASPNET
ESTO NI SE TE OCURRA
  • Impersonar el hilo de ejecución de la aplicación con un usuario Adminsitrador
La gente de sistemas nunca te lo dará y además no me parece una buena solución puesto que vulnera muchos principios de seguridad como en el primer caso.
  • Hacer una impersonación sólo cuando generas el Informe con una cuenta de usuario que sea Adminsitrador 
La gente de sistemas nunca te lo dará
Bueno, pues visto que esto va a ser que no, de repente, cacharreando con los Servicios de Componentes encuentro una cosita que se llamaConfiguración DCOM (Distributted Component Object Model) y al expandirlo me encuanto con esto:
Síííííí!!!! Aplicación Microsoft Excel, esto pinta bien y además tiene propiedades, así que pinchamos:
Juer y encima tiene una pestaña de Seguridad
Así que marcamos el check Personalizar de los Permisos de inicio y activación y pulsamos el botón Modificar para dar permisos al Usuario/Grupo que desamos:
Aceptamos todo y con esto hemos resuelto el maldito error. En mi caso hemos dados permisos a un Grupo que contiene a los usuarios que acceden a la aplicación. (Aunque la imagen corresponde al equipo mio de casa ;))
Por último y por cuestiones de performance en nuestra aplicación es necesario liberar todos los objetos COM que utilicemos, para que no se queden esos malditos procesos llamados EXCEL (Os lo digo por experiencia propia), que aperecen a porrillo en el Administrador de Tareas, y para ello os dejo este enlace del Support de Microsoft:
Con la solución que propone conseguí eliminar eso malditos procesos que parecían desaparecer con el oApp.Quit(); oApp = null; pero que en realidad no desaparecían y se estaban acumulando llevandose 36 Mb de memoria cada uno.
Bueno pues espero que os sirva y que no tengáis que romperos tanto el coco y os encontréis tantos probelmas como me he encontrado yo.

Aplicaciones Mobiles con Jquery


Continuamos con la segunda parte de esta introducción a jQuery Mobile, un framework de desarrollo UI para aplicaciones web en móviles.
En este artículo hablaremos de los aspectos básicos del framework: $.mobile, métodos y eventos, los atributos data-* de HTML5, y la creación de una aplicación web móvil con jQuery Mobile.
Si quieres saber cómo el nuevo framework de jQuery Mobile puede ayudarte a desarrollar aplicaciones web para móviles, con facilidad, este artículo es para ti...

$.mobile y los métodos y eventos soportados

El objeto JavaScript jQuery la mayoría de veces es referido con el signo del dólar ($). jQuery Mobile framework extiende el core de jQuery con plugins móviles, que incluyen el mobile o $.mobile, los cuales definen varios eventos y métodos. Algunos de los métodos expuestos por $.mobile están descritos en la siguiente tabla.
MétodoUso
$.mobile.changePagePara cambiar la programación de una página a otra. Por ejemplo, para ir a una página weblog.php usando un slide de transición, usamos $.mobile.changePage(“weblog.php”, “slide”).
$.mobile. pageLoadingPara mostrar u ocultar el mensaje “Esta página se esta cargando”. Por ejemplo, para ocultar el mensaje, usamos $.mobile.pageLoading(true).
$.mobile.silentScrollPara hacer scroll a una posición Y en particular, sin realizar el evento scroll. Por ejemplo, para hacer scroll a la posición Y=50, usamos $.mobile.silentScroll(100).
$.mobile.addResolutionBreakpointsjQuery Mobile define algunos breakpoints para un mínimo/máximo de clases. Hay que llamar a este método para añadir breakpoints. Por ejemplo, para añadir una clase min/max de 800 pixeles de ancho, usamos $.mobile.addResolutionBreakpoints(800).
$.mobile.activePageRefiere a la página activa actual.
También hay varios eventos que se pueden usar con los métodos bind() o live(), como la inicialización de jQuery Mobile, eventos de toque, cambios de orientación, eventos de scroll, eventos de mostrar/ocultar página, eventos de inicialización de página y eventos de animación.
Por ejemplo, los eventos de toque (touch events) incluyen taptaphold y varios eventosswipe. Los eventos de Scroll incluyen scrollstart y scrollstop. Los eventos de Página permiten recibir notificaciones: Antes de la creación de la página, cuando una página es creada, sólo antes que la página se muestre u oculte, y cuando la página es mostrada u ocultada.
En el siguiente ejemplo realizamos un evento específico cuando jQuery Mobile empieza a ejecutarse:
$(document).bind("mobileinit", function(){ //apply overrides here });
El evento de anterior nos permite reemplazar los valores por defecto cuando se inicia jQuery Mobile. Varias opciones pueden ser sobrescritas, por ejemplo:
  • LoadingMessage – Define el texto por defecto que aparece cuando una página se carga.
  • defaultTransition – Define la transición por defecto para los cambios de una página que usa Ajax.
Hay más parámetros de configuración que podemos sobreescribir si lo necesitamos. Podemos ver la documentación de jQuery Mobile o el código fuente del ejemplo, para más detalles.
También podemos enlazar otros eventos que nos permiten crear aplicaciones dinámicas basadas en los eventos “touch” y “page”.

Los atributos data-* de HTML5

jQuery Mobile se basa en los atributos data-* de HTML5 para soportar varios elementos de UI, transiciones y estructura de la página. Sin embargo, estos son descartados silenciosamente por los navegadores que no los soportan.
La siguiente tabla muestra como usar los atributos de data-* para crear componentes de UI.
ComponenteAtributo data-* de HTML5
Barras de herramientas de Footer y Header
<div data-role="header">
<div data-role="footer">
Cuerpo del contenido<div data-role="content">
Botones
<a href="index.html" data-role="button"
data-icon="info">Botón</a>
Botones agrupados
<div data-role="controlgroup">
<a href="index.html" data-role="button">Si</a>
<a href="index.html" data-role="button">No</a>
<a href="index.html" data-role="button">Muy bien</a>
</div>
Botones en línea
<div data-inline="true">
<a href="index.html" data-role="button">Foo</a>
<a href="index.html" data-role="button" data-theme="b">Bar</a>
</div>
Elemento del formulario (Menú select)
<div data-role="fieldcontain">
<label for="select-options" class="select">Escoge una opción:</label>
<select name="select-options" id="select-options">
<option value="option1">Opción 1</option>
<option value="option2">Opción 2</option>
<option value="option2">Opción 3</option>
</select>
</div>
Vistas de Lista Básica
<ul data-role="listview">
<li><a href="index.html">Uno</a></li>
<li><a href="index.html">Dos</a></li>
<li><a href="index.html">Tres</a></li>
</ul>
Diálogos
<a href="foo.html" data-rel="dialog">Abrir diálogo</a>
<a href="dialog.html" data-role="button" data-inline="true"
data-rel="dialog" data-transition="pop">Abrir diálogo</a>
Transiciones<a href="index.html" data-transition="pop" data-back="true">
La documentación de jQuery Mobile tiene una lista completa de la sintaxis de data-*soportada.

Estructura de una página jQuery Mobile

En esta sección dareamos una mirada rápida a la estructura de una página con jQuery Mobile. jQuery Mobile cuenta con unas directrices sobre la estructura de las páginas en si mismas. En general, una estructura de página debe tener las siguientes secciones:
Barra de encabezado (Header Bar)
Normalmente contiene el título de la página y el botón Atrás.
Contenido (Content section)
El contenido de nuestra aplicación.
Barra de pié (Footer Bar)
Normalmente contiene los elementos de navegación, la información de copyright o la información que necesitemos añadir en el footer.
Por ejemplo, la siguiente imagen muestra las diferentes secciones.
Secciones Pagina jQuery Mobile
Las barras de la cabecera y del pié tienen soporte a las opciones de pantalla completa y posición fija. La posición fija (fixed position) hace que las barras estén estáticas al momento de desplazarse. El posicionamiento de pantalla completa funciona de la misma manera que el fijo, excepto que las barras sólo se muestran al hacer clic en la página (para tratar de no obstruir la visión del contenido completo). El resto de esta sección explora el código HTML de una estructura de página genérica.
La definición de una página HTML ensimisma es !DOCTYPE html>, la cual define un tipo de documento HTML5.
La sección head del HTML carga tres componentes importantes de jQuery Mobile:
  • La librería Core de jQuery
  • La librería de jQuery Mobile: La parte específica para móviles del framework de jQuery.
  • jQuery Mobile CSS – El CSS que define los elementos UI del core de JQuery Mobile. Esto define las transiciones y distintos widgets UI, como los sliders y botones, y hace un uso intensivo de animaciones y transformaciones con Webkit.
A continuación, mostramos como se define la sección head del HTML.
<html> 
    <head> 
        <meta charset="utf-8" /> 
        <title>Intro to jQuery Mobile</title> 
        <link rel="stylesheet" href="http://code.jquery.com/mobile
/1.0a2/jquery.mobile-1.0a2.min.css" /> 
        <script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.0a2
/jquery.mobile-1.0a2.min.js"></script> 
    </head>
La siguiente sección de código HTML define la página ensimisma, vean cómo usamos el atributo data-role=”page”.
    <body> 

        <div data-role="page" id="page1">
El atributo id es necesario únicamente si hay múltiples bloques en un mismo archivo HTML, pero es una buena practica definirlo.
El siguiente par de trozos de código muestran como se definen las secciones delheadercontent y footer de la página. El header bar típicamente consiste en el título de la página y en el botón “Atrás”, como se muestra a continuación.
                <div data-role="header"> 
                <h1>Header Bar</h1> 
            </div><!-- /header –>
En este caso, la cabecera consiste unicamente en un título H1. El fuerte del contenido va luego de la cabecera, como se muestra a continuación.
            <div data-role="content">   
                <p>Content Section</p>      
            </div><!-- /content -->
En este ejemplo, mostramos sólo un párrafo simple, pero es aquí donde debemos añadir las listas, botones, formularios, etc.
El footer es donde típicamente colocamos los elementos de navegación e información de copyright, por ejemplo:
            <div data-role="footer"> 
                <h4>Footer Bar</h4> 
            </div><!-- /footer --> 
        </div><!-- /page --> 

    </body> 
</html>
La sección de footer es muy sencilla. Añadir una barra de navegación no es muy complicado, por ejemplo.
<div data-role="footer" class="ui-bar">
    <div data-role="controlgroup" data-type="horizontal">
    <a href="index.html" data-role="button">Today</a>
    <a href="index.html" data-role="button">Tomorrow</a>
    <a href="index.html" data-role="button">Week</a>
    <a href="index.html" data-role="button">No date</a>
    </div>
</div><!-- /footer -->
Ahora vemos, la sección del footer con una barra de navegación del sitio.
Footer con barra de navegación

Definición de múltiples páginas locales

El ejemplo anterior abarcó una sola página. jQuery Mobile también ofrece soporte para múltiples páginas en un único documento HTML. Las página múltiples son locales, internamente enlazadas y agrupadas con fines de precarga. La estructura de las páginas múltiples es similar a la del anterior ejemplo, excepto que contiene múltiples atributos data-role=”page”. Por ejemplo.
<div data-role="page" id=page1">
   <div data-role="header">
    :
   </div>
   <div data-role="content">
    :
   </div>
   <div data-role="footer">
    :
   </div>
</div>
:
:
<div data-role="page" id=page2">
   <div data-role="header">
    :
   </div>
   <div data-role="content">
    :
   </div>
   <div data-role="footer">
    :
   </div>
</div>
Cuando se referencia a una página que es local al mismo documento HTML, jQuery Mobile automáticamente se conecta con la referencia. Cuando se referencia una página externa, jQuery Mobile mostrará un cargador (loading spinner). Si ocurre un error, el framework automáticamente manejará y mostrará un mensaje pop-up de error.

Transiciones de página

jQuery Mobile provee soporte a las transiciones de páginas basadas en CSS (inspiradas en jQtouch), las cuales son aplicadas cuando navegamos a una página nueva o regresamos a una anterior. Las transiciones incluyen:
Slide
Provee una transición horizontal
Slideup y Slidedown
Provee transiciones hacia arriba o abajo de la pantalla
Pop
Provee una explosión como tipo de transición
Fade
Provee una transición fading
Flip
Provee una transición flip.
Podemos añadir las transiciones a una página de dos formas diferentes:
  • Añadir un atributo data-transition al enlace, usando <a href=”index.html” data-transition=”pop” data-back=”true”>Usar el atributo data-transition en páginas estáticas.
  • Programar, usando $.mobile.changePage(“pendingtasks.html”, “slideup”);
    Usar la aproximación de programación cuando trabajamos con páginas dinámicas.

List Views

Las list views, un tipo fundamental de elemento UI, son usadas comunmente en aplicaciones móviles. jQuery Mobile es compatible con varios list viewslist basic, nested, numbered y read-only; split buttons; list dividers; count bubbles; thumbnails; icons; search filter bars; insert styled lists; y theming lists.
A continuación mostramos un list view básico. Este list view es creado usando el atributo data <ul data-role=”listview”>.
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Intro to jQuery Mobile</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile
/1.0a2/jquery.mobile-1.0a2.min.css" />
        <script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.0a2
/jquery.mobile-1.0a2.min.js"></script>
    </head>
    <body>

        <div data-role="page">

            <div data-role="header">
               <h1>Facebook Friends</h1>
            </div><!-- /header -->

            <div data-role="content">
               <p>

               <ul data-role="listview" data-inset="true">

                  <li>
                  <a href="index.html">Get Friends</a>
                  </li>

                  <li>
                  <a href="index.html">Post to Wall</a>
                  </li>

                  <li><a href="index.html">Send Message</a></li>
               </ul>

               </p>

            </div><!-- /content -->

            <div data-role="footer">
            </div><!-- /footer -->
        </div><!-- /page -->

    </body>
</html>
Dentro del <ul data-role=”listview”/> podemos definir items <li>. Este es un perfecto ejemplo de cómo jQuery Mobile extiende la sintaxis básica de HTML. El resultado del código podemos verlo en la siguiente imagen.
jQuery Mobile con Select List

Formularios (Forms)

Los formularios son otros tipos comunes de artefactos usados para enviar información al servidor. jQuery Mobile soporta varios componentes UI de formulario: text inputs, search inputs, slider, flip toggle switch, radio buttons, checkboxes, select menus ytheming forms. Ellos pueden ser creados muy fácilmente.
Los select menus son manejados nativamente <select name=select-options” id=”select-options”>, pero jQuery Mobile los mejora en su “look and feel”. La declaración <div data-role=”fieldcontain”> agrupa diferentes valores con propósitos de visualización. El formulario ensimismo es definido nativamente por <form action=”…” method=”…”>.
El siguiente código muestra el formulario y su contenido.
<form action="forms-results.php" method="get"> 
    <fieldset> 
        <div data-role="fieldcontain">
            <label for="select-options" class="select">Choose 
an option:</label>
            <select name="select-options" id="select-options">
                <option value="option1">Option 1</option>
                <option value="option2">Option 2</option>
                <option value="option2">Option 3</option>
            </select>
        </div>
        <button type="submit">Submit</button> 
    </fieldset> 
</form>
Cuando escogemos el menú de selección, jQuery Mobile muestra un pop-up, que vemos en la imagen, con todos los valores de selección, y se cerrará automáticamente luego de la selección.
 jQuery Mobile muestra un pop-up
Mientras que los atributos de action y method del formulario son definidos correctamente, jQuery Mobile se encarga de las transiciones entre el formulario, la invocación Ajax y la página de resultados, y muestra una tuerca (de página cargando) si es necesario.

Otros componentes UI

Hay muchos más elementos UI y variaciones de elementos, que pueden ser explorados en el sitio web de jQuery Mobile y en su documentación. Para completar lo que hemos aprendido en estos dos artículos, sería bueno que echaramos un ojo a la info: collapsible content, layout grids, theming y el resto de list view y forms.

Conclusión

Esta mini-serie de artículos nos ha introducido al framework de JavaScript jQuery Mobile. Hemos visto lo básico del framework y como escribir páginas web funcionales sin necesidad de escribir una línea de código JavaScript. Si necesitas manipular documentos HTML, podemos hacerlo con algo del core de jQuery. Hemos visto lo básico de páginas y navegación, toolbars, controles de formulario y efectos de transición. jQuery Mobile provee numerosos métodos, eventos y propiedades que podemos usar. Que este par de artículos nos sirva de base para buscar más información sobre los componentes de interfaz de usuario que no se han tratado.