Blog

  • Menú Contextual en tu Aplicación Web

    Menú Contextual en tu Aplicación Web

    ¿Quieres incluir un menú contextual en tu página web? Puedes hacerlo de una forma sencilla incorporando el plugin ContextMenu de jQuery. Se trata de un plugin ligero que te permite sobrescribir selectivamente el menú contextual del navegador al pulsar sobre el botón derecho del ratón. También comentaré la forma de que responda tanto a la pulsación sobre el botón derecho como al izquierdo.

    Sus características son las siguientes:

    • Uso de múltiples menús diferentes en un página
    • Un menú puede ser asociado para que responda a varios elementos de la página
    • Los estilos de los menús son totalmente personalizables
    • Permite opciones de menú con iconos
    • Acciones asociadas a callbacks sensibles al contexto.

    El único requisito es haber incluido en la aplicación el framework jQuery. Funciona en todos los navegadores, por lo que no tendremos problemas con compatibilidades. Puedes descargarlo desde aquí: jquery.contextmenu.r2.js para incluirlo en tus páginas o aplicaciones web

    Uso

    La estructura del menú se construye con HTML, incluyendo cada opción de menú en una lista no ordenada dentro de una capa, con la clase «contextMenu» y con el id que prefieras y que utilizarás para referenciarlo. Dentro de la página esta capa puede ir en cualquier posición.

    Puedes definir tantos menús como necesites. Cada elemento <li> de la lista de la capa actuará como una opción de menú. Dando a cada <li> un id único las acciones pueden ser ligadas a ese menú.

    A continuación se muestra un ejemplo. En la página HTML incluiremos el código del div del menú con las opciones que necesitamos:

        <div id="myMenu1" class="contextMenu" style="display: none">
    
          <ul>
    
            <li id="open"><img src="folder.png" /> Open</li>
    
            <li id="email"><img src="email.png" /> Email</li>
    
            <li id="save"><img src="disk.png" /> Save</li>
    
            <li id="close"><img src="cross.png" /> Close</li>
    
          </ul>
    
        </div>

    El código javascript para enlazar cada opción con el código a ejecutar es el siguiente:

        $('span.demo1').contextMenu('myMenu1', {
          bindings: {
    
            'open': function(t) {
              alert('Trigger was '+t.id+'\nAction was Open');
            },
    
            'email': function(t) {
              alert('Trigger was '+t.id+'\nAction was Email');
            },
    
            'save': function(t) {
              alert('Trigger was '+t.id+'\nAction was Save');
            },
    
            'delete': function(t) {
              alert('Trigger was '+t.id+'\nAction was Delete');
            }
          }
    
        });

    Menú de ejemplo

    Parámetros

    menu_id: Puedes asociar uno o más elementos de la página a un menú. Por ejemplo si invocamos al context menú de esta forma $("table td").contextMenu("myMenu1"), todas las celdas de una tabla mostrarán el menú al pulsar sobre ellas el botón derecho.

    Configuración: Podemos usar la configuración por defecto o bien podemos opcionalmente  modificarla. En el ejemplo de arriba hemos visto cómo asociar la acción que se va a ejecutar para cada id del menú. Para añadir más deben ir separados por comas. El elemento que dispara el menú actual es pasado como parámetro.

    • menuStyle: Contiene pares nombre-valor para aplicar estilos al tag <ul> del menú.
    • itemStyle: Contiene pares nombre-valor para aplicar estilos a los elementos <li> del menú
    • itemHoverStyle: Idéntico al anterior pero aplica cuando se pasa el ratón sobre el elemento <li>, para resaltarlo, etc.
    • shadow: Boolean que identifica si se quiere mostrar la sombra del menú. Por defecto es true.

    Puedes ver más en la página oficial del plugin. También es posible ampliar las opciones por defecto de todos los menús invocando al método defaults. Cualquier configuración excepto bindings puede ser usado como por defecto:

      $.contextMenu.defaults({
        menuStyle : {
          border : "2px solid green"
        },
    
        shadow: false,
        onContextMenu: function(e) {
          alert('Did someone asked for a context menu?!');
        }
      });

    Menú contextual pulsando el botón izquierdo del ratón

    Por defecto, este plugin funciona pulsando sobre el elemento que queremos que muestre el menú, con el botón derecho del ratón. Para modificar este comportamiento, y que se muestre igualmente al pulsar sobre el botón izquierdo, debemos abrir el fichero descargado del plugin (jquery.contextmenu.r2.js) y abrirlo para editar. Necesitamos modificar la línea:

    return $(this).bind('contextmenu', function(e) {

    por esta otra:

    return $(this).bind('click', function(e) {
  • Tareas programadas con Spring y Quartz

    Tareas programadas con Spring y Quartz

    En un post anterior explicamos cómo utilizar las clases wrapper de Spring para ejecutar una tarea a intervalos regulares de tiempo dentro de una aplicación web J2EE. En esta publicación integraremos Spring con el planificador Quartz para programar la misma tarea dentro de una aplicación J2EE.

    Quartz es un servicio opensource de planificación de tareas que puede ser integrado con cualquier aplicación Java, desde la más pequeña aplicación stand-alone al más extenso sistema de e-commerce. Quartz puede ser utilizado para crear planificaciones simples o complejas para ejecuciones de decenas, cientos, o incluso miles de trabajos cuyas tareas son definidas como componentes Java estándar. Además incluye soporte para transacciones JTA y clustering. Es de uso libre bajo la licencia Apache 2.0.

    Para instalarla en nuestra aplicación simplemente descargaremos el fichero quartz-x.x.x.tar.gz desde la web de descargas y extraeremos el fichero quartz-all-x.x.x.jar para incorporarlo a nuestra aplicación. En mi caso utilicé la versión 1.8.6, pese a no ser la última, debido a mi versión de Spring. Si tienes problemas con la última, te recomiendo que vayas bajando de versión hasta dar con la idónea. Dentro del fichero comprimido tar.gz existe una carpeta lib con las dependencias que tiene quartz con otras librerías. En mi caso necesité incluir en mi aplicación la librería slf4j-api-x.x.x.jar.

    Lo primero que vamos a crear es la tarea a ejecutar. Será un método público dentro de una clase pública, tal y como se muestra en el siguiente código:

    package es.activity.schedule;
    
    public class RunMeTask
    {
    	public void printMe() {
    		System.out.println("Ejecutando tarea programada");
    	}
    }

    A continuación abrimos para editar el fichero XML de contexto de nuestra aplicación web Spring y añadimos un bean que haga referencia a la clase anterior:

    <bean id="runMeTask" class="es.activity.schedule.RunMeTask" />

    Una vez definida la tarea pasamos a configurar los principales conceptos de Quartz: Job, Trigger y Scheduler:

    Job

    Es la unidad de trabajo o tarea a ejecutar. Sería cualquier implementación de la interfaz org.quartz.Job. En Spring se han incluido varias implementaciones de la interfaz pero nosotros vamos a utilizar MethodInvokingJobDetailFactoryBean, la cual nos permite la ejecución de un método de cualquier clase java:

    <bean id="schedulerJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
       <property name="targetObject" ref="runMeTask"></property>
       <property name="targetMethod" value="printMe"></property>
       <property name="concurrent" value="false"></property>
    </bean>

    Trigger

    Es la unidad que conoce los detalles de la ejecución de la tarea y los instantes en los que se debe ejecutar. Sería cualquier implementación de la interfaz org.quartz.Trigger. Es este caso es el propio Quartz el que proporciona diversas implementaciones:

    SimpleTrigger

    Permite especificar una hora de comienzo, una hora de fin y un intervalo de ejecución, similar al ejemplo del post en el que hablábamos sobre la clase Timer incluida en el JDK. En el ejemplo ejecutamos el job tras un segundo de retardo y posteriormente cada 60 segundos.

    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
            <property name="jobDetail" ref="schedulerJob" />
            <property name="repeatInterval" value="60000" />
            <property name="startDelay" value="1000" />
    </bean>

    CronTrigger

    Permite especificar expresiones cron de Unix para establecer fechas y horas de ejecución del job. En el ejemplo se ejecuta el job de lunes a viernes a las 8 de la mañana.

    <bean id="timerCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">>
            <property name="jobDetail" ref="schedulerJob"></property>
            <property name="cronExpression" value="0 0 8 ? * MON-FRI"></property>
    </bean>

    Más información sobre expresiones cron en los siguientes enlaces:

    1. http://en.wikipedia.org/wiki/CRON_expression
    2. http://www.quartz-scheduler.org/documentation/quartz-1.x/examples/Example3

    Scheduler

    Por último tenemos que lanzar la ejecución de nuestro job mediante un planificador que gestione la ejecución a partir de la información especificada en el Trigger. Spring incorpora la clase SchedulerFactoryBean para ejecutar uno o varios trigger:

    <bean id="GiaScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="timerCronTrigger"></ref>
                </list>
            </property>
    </bean>

    Con todo esto especificado en el fichero de contexto xml, desplegamos la aplicación en el servidor de aplicaciones y se ejecutará la tarea con la programación especificada.

     

  • Tareas programadas con Spring Framework y JDK Timer

    Tareas programadas con Spring Framework y JDK Timer

    Seguro que en más de una ocasión, durante el desarrollo de una aplicación has necesitado ejecutar una tarea de forma periódica. Para desarrollar esto, desde la versión 1.3 del JDK se incluye las clases java.util.Timer y java.util.TimerTask. Estas clase facilitan la programación de tareas para ejecuciones futuras en un thread en segundo plano. Las tareas pueden ser programadas para ejecutarse una vez o múltiples veces a intervalos regulares.

    En el caso de que necesites una planificación más compleja, la clase Timer se quedará corta en varios aspectos y deberás utilizar un planificador como Quartz o similar. En este hilo de StackOverflow puedes ver otras alternativas. En este artículo vamos a utilizar las clases wrapper de Spring, que internamente hacen uso de las del JDK, para ejecutar una tarea a intervalos regulares de tiempo dentro de una aplicación web J2EE con el framework de Spring.

    Lo primero que vamos a crear es la tarea a ejecutar. Será un método público dentro de una clase pública, tal y como se muestra en el siguiente código:

    package es.activity.schedule;
    
    public class RunMeTask
    {
    	public void printMe() {
    		System.out.println("Ejecutando tarea programada");
    	}
    }

    A continuación abrimos para editar el fichero XML de contexto de nuestra aplicación web Spring y añadimos un bean que haga referencia a la clase anterior:

    <bean id="runMeTask" class="es.activity.schedule.RunMeTask" />

    Vamos a definir a continuación, en el mismo fichero, el método de la clase que ejecutará el código de la tarea. Spring incorpora la clase MethodInvokingTimerTaskFactoryBean para reemplazar la clase TimerTask del JDK.

    <bean id="schedulerTask" 
      class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
    	<property name="targetObject" ref="runMeTask" />
    	<property name="targetMethod" value="printMe" />
    </bean>

    Ahora vamos a definir cada cuánto se ejecutará utilizando la clase ScheduledTimerTask, que reemplaza a la clase Timer del JDK. Le pasamos como propiedades al bean tanto el retardo (delay) para la primera ejecución, como el intervalo (period) para sucesivas ejecuciones. Ambos valores en milisegundos. En el ejemplo se ejecutará un segundo después del despliegue de la aplicación y a continuación cada 60 segundos.

    <bean id="timerTask"
    	class="org.springframework.scheduling.timer.ScheduledTimerTask">
    	<property name="timerTask" ref="schedulerTask" />
    	<property name="delay" value="1000" />
    	<property name="period" value="60000" />
    </bean>

    Hasta ahora se trata de configurar de manera declarativa lo referente a la tarea. Vamos a ejecutar el timer para que comience la ejecución:

    <bean class="org.springframework.scheduling.timer.TimerFactoryBean">
    	<property name="scheduledTimerTasks">
    		<list>
    			<ref local="timerTask" />
    		</list>
    	</property>
    </bean>

    Cómo ves no es necesario introducir ninguna llamada por código a la tarea programada. La clase TimerFactoryBean se encarga de ejecutar el código del método PrintMe() durante el despliegue de la aplicación en el servidor, con un retardo de 1 segundo la primera vez y luego cada 60 segundos.

    Actualización (24/01/2013). Para completar la información quizás te interese cómo integrar Spring con el planificador Quartz. Por ello publiqué otro artículo posteriormente con el título «Tareas programadas con Spring y Quartz».

  • Ruby on Rails: Autenticación y Autorización (I)

    Ruby on Rails: Autenticación y Autorización (I)

    Uno de los puntos débiles (o fuertes, según se mire) de Ruby on Rails (RoR) es que requiere de la configuración de su propia autenticación y sistemas de autorización. Tiene sentido teniendo en cuenta que se trata de un framework para el desarrollo de aplicaciones, más que un completo sistema de gestión de contenidos como Drupal, por ejemplo. Esto requiere de más tiempo para construir una aplicación web básica. En este post explicaremos la manera de configurar un sistema de autenticación para una aplicación desarrollada con RoR. Se requiere conocimientos de Ruby y tener instalado el mismo en el sistema.

    A veces se confunde Autenticación con Autorización. La autenticación o autentificación es cualquier proceso mediante el cual se verifica que alguien es quien dice ser. Esto suele ser gestionado por una pantalla de inicio de sesión. La autorización es cualquier proceso por el cual a alguien se le permite estar donde quiere ir, o tener la información que quiere tener. En un ejemplo como el correo electrónico, al entrar en el sistema, la autenticación indica al proveedor de correo electrónico que yo estoy accediendo a consultar mis mensajes. (El proceso por el cual, una vez dentro, se me permite el acceso a qué páginas o recursos sería la autorización).

    Se puede crear un sistema de autenticación desde cero, creando nuestro propio modelo de datos, nuestras vistas e incluso utilizar el sistema de encriptación que deseemos para las contraseñas. Aquí vamos a aprender a configurar de manera básica Devise. Devise es una solución de autenticación para Rails, siguiendo el estándar MVC, basada en el concepto de modularidad, es decir, se utiliza lo que se necesita.

    Lo primero que tenemos que hacer es abrir un terminal con el entorno Rails configurado y listo, e instalamos Devise con el comando «gem install devise»

    A continuación debemos configurar Devise. Para ello vamos a crear nuestra aplicación Rails a la que vamos a llamar «mysecureapp». Para ello ejecutamos el comando «rails new mysecureapp»

    Nuestra aplicación RoR ha sido creada en el directorio en el que hemos ejecutado el comando. Cambiamos al directorio recién creado «mysecureapp» y editamos el fichero «Gemfile. Vamos a añadir la línea gem ‘devise’ como mostramos abajo:

    gem 'sqlite3'
    
    gem 'devise'

    El siguiente paso es instalar Devise usando el comando «rails generate devise:install» que producirá el siguiente resultado:

    Seguimos las instrucciones que nos indica la salida del comando. Añadimos la siguiente línea al fichero de nuestra aplicación «mysecurity/config/environments/development.rb»:

    config.action_mailer.default_url_options = { :host => 'localhost:3000' }

    Añadimos los mensajes en el fichero «app/views/layouts/application.html.erb» dentro del body de la página:

    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>

    Cambiamos al directorio «mysecurity/config» y añadimos al fichero de rutas routes.rb la siguiente línea:

    root :to => "home#index"

    A continuación generaremos el modelo para el objeto Usuario (rails generate devise user) y ejecutaremos «rake db:migrate» para crear las tablas en la base de datos. Si queremos que el nombre del modelo y de la tabla que almacena los usuarios se llame de manera diferente (admin, member, etc.) debemos indicarlo al generarlo (rails generate devise NOMBRE_MODELO). Recordemos que si no especificamos otra base de datos, las tablas se crean en la base de datos por defecto para desarrollo, SQLite que incorpora RoR. Si el nombre del modelo es «user» creará una tabla con el nombre en plural «users»:

    Comprobamos que todo ha funcionado correctamente ejecutando el servidor Rails (ejecutar el comando «rails server») y en un navegador tecleamos la siguiente URL «http://localhost:3000/users/sign_in». Si todo ha ido bien veremos que se muestra lo siguiente:

    Devise nos genera URLs para login, alta de usuario, cerrar sesión, cancelar usuario, recordar contraseña, editar usuario, etc. Para ver todas las rutas podemos ejecutar el comando «rake routes» desde la línea de comandos:

    Podemos usar el complemento SQLite Manager de Firefox para ver la base de datos de desarrollo SQLite. Está localizada en el sistema de ficheros, dentro del directorio «mysecurity/db» de nuestra aplicación, en el fichero development.sqlite3. Podemos observar las columnas generadas en la tabla «users».

    Devise creará varios métodos helpers para usar dentro de nuestros controladores y vistas. Para configurar que un controlador requiere autenticación del usuario añadimos el siguiente filtro:

    before_filter :authenticate_user!

    Para verificar que un usuario ha realizado login, usamos el siguiente helper:

    user_signed_in?

    Para conocer el usuario que se ha logado:

    current_user

    Para acceder a la variable del entorno de sesión

    user_session

    Hay que tener en cuenta que si habíamos renombrado nuestro modelo con otro nombre como «member», por ejemplo, hay que sustituir la palabra «user» por «member»:

    before_filter :authenticate_member!
    
    member_signed_in?
    
    current_member
    
    member_session

    Es importante conocer que todas las vistas están empaquetadas en Devise. Para generarlas y tener accesibilidad para poder personalizarlas ejecutamos el siguiente comando:

    rails generate devise:views

    Esto generará las vistas en el directorio /app/views/devise.

    Ahora que tenemos la autenticación configurada y funcionando podemos empezar a mejorarla. Nos gustaría tener un enlace en la parte superior de la página que nos diga si tenemos sesión iniciada y otro que nos permita iniciar y cerrar una sesión.

    Lo podemos hacer modificando el fichero de layout de la aplicación de forma que los enlaces sean visibles en todas las páginas. Añadamos las siguientes líneas justo después del código que muestra los mensajes:

    <div id="user_nav">
      <% if user_signed_in? %>
        Conectado como <%= current_user.email %>. No eres t&uacute;?
        <%= link_to "Log off", destroy_user_session_path, :method => :delete%>
      <% else %>
        <%= link_to "Alta", new_user_registration_path %> o
        <%= link_to "Login", new_user_session_path %>
      <% end %>
    </div>

    Como puede verse, con Devise es muy sencillo configurar toda la funcionalidad de autenticación, añadiendo sin esfuerzo la capacidad de registrar nuevos usuarios y permitirles iniciar y cerrar sesión.

  • JScrollPane, Barras de Scroll en Divs

    JScrollPane, Barras de Scroll en Divs

    ¿Necesitas incluir barras de scroll a una o más capas dentro de tu página? En este post encontraréis una posible solución utilizando un plugin jQuery llamado jScrollPane.

    En ocasiones llenamos nuestras páginas de de mucho contenido dentro de uno o varios divs. Más tarde nos damos cuenta de que el área reservada en un div para mostrar ciertos elementos o texto se ha quedado pequeño, y al crecer la página la página deja de verse correctamente. Tanto si este es tu problema como si únicamente quieres incluir scroll a una capa este plugin de jQuery te ayudará.

    Lo primero que debemos hacer es descargarlo desde http://jscrollpane.kelvinluck.com/#download, necesitaremos lo siguiente:

    • jquery.jscrollpane.css. Estilos básicos CSS necesarios para hacerlo funcionar
    • jquery.jscrollpane.min.js. Es la versión reducida del fichero javascript de jScrollPane. Podemos usar el fichero sin minimizar, de manera que nos permita ver el código y los comentarios sobre el mismo.
    • Obviamente, la librería jQuery.
    • jquery.mousewheel.js. Opcional. Es el plugin mousewheel, para hacer scroll con la rueda que incorporan la mayoría de los ratones.
    • mwheelIntent.js. Opcional. Es el plugin mWheelIntent para mejorar la usabilidad usando la rueda del ratón.

    El uso es muy sencillo, después de descargar los ficheros necesarios los incluimos en el head de nuestro código html:

    <!-- estilos jScrollPane -->
    <link type="text/css" href="jquery.jscrollpane.css" rel="stylesheet"/>
    
    <!-- versión de jQuery  -->
    <script type="text/javascript" src="jquery.min.js"></script>
    
    <!-- El plugin mousewheel plugin - opcional - provee soporte para la rueda del ratón -->
    <script type="text/javascript" src="jquery.mousewheel.js"></script>
    
    <!-- Fichero javascript de jScrollPane -->
    <script type="text/javascript" src="jquery.jscrollpane.min.js"></script>

    Ahora tenemos que inicializar jScrollPane al cargar la página de la forma:

    <script type="text/javascript">
    	$(document).ready(function($){
    		var pane = $("#cajafechas")
    		pane.jScrollPane();
    		var api = pane.data('jsp');
    		api.scrollToBottom();
    	});
    </script>

    En el ejemplo tenemos una capa con el id cajafechas, a la que aplicamos el plugin. Esta capa se va completando con fechas de forma dinámica, cuando el número de fechas sea muy grande, aparecerán las barras de scroll. Bastaría con poner la línea $("#cajafechas").jScrollPane();, pero necesitamos que al iniciar la página el scroll se desplace al final. Para ello llamamos a un método del API, scrollToBottom().

    Hay muchas formas de usar jScrollPane (animaciones, estilos de barra, etc), bien a través de parámetros de configuración o bien a través del API. En la página del desarrollador se pueden encontrar multitud de ejemplos.

     

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para su aceptación y la de nuestra política de cookies.

ACEPTAR
Aviso de cookies