Bloquear el cierre de una ventana modal en BootStrap 3

Por defecto, las ventanas modales de Bootstrap 3 se cierran de tres formas:
  • Al pulsar la tecla escape
  • Al hacer clic en el botón de cierre (una equis en la esquina superior derecha)
  • Al hacer clic fuera de la ventana modal (la zona sombreada en negro)
Esto es deseable en interfaces de teclado y ratón, pero al pasar a una interfaz táctil he visto lo fácil que es tocar la zona sombreada con la palma de la mano sin querer, provocando que la ventana modal se cierre. Este comportamiento lo podemos desactivar de forma sencilla de dos formas:
  1. Vía HTML: incluyendo el parámetro data-backdrop="static" en el div de la ventana modal
  2. Vía JavaScript: pasando un JSON con la opción backdrop : 'static'
 Ejemplos:

Usando data-backdrop
<div class="modal fade" data-backdrop="static" tabindex="-1" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title">Título</h4>
      </div>
      <div class="modal-body">
        <p>Una ventana modal</p>
      </div>
    </div>
  </div>
</div>
       
Usando backdrop como opción
$('#myModal').modal({
  backdrop: 'static'
})

Referencias: Documentación de Modal en getbootstrap.com

Cómo ejecutar un código JavaScript tras X segundos

JavaScript dispone de dos funciones nativas (setTimeout() y setInterval()) muy útiles para ejecutar código tras un tiempo especificado. Vamos a ver cómo se utilizan.

setTimeout(func, x)

Ejecuta el código func al pasar x milisegundos. Parámetros:
  • func: función anónima, nombre de una función o variable que apunta a una función
  • x: el número de milisegundos de retraso
Soporte: Todos los navegadores (desde IE 4)

Así si, por ejemplo, queremos mostrar un mensaje a los tres segundos de cargar una página escribiremos el siguiente script antes de </body>
<script type="application/javascript">

setTimeout(
    function(){
        alert('Bienvenido');
    },
    3000
);

</script>
o bien:
<script type="application/javascript">

function saludo(){
  alert('Bienvenido');
}

setTimeout(saludo, 3000);

</script>
La mayor pega de esta versión de setTimeout() es que no permite el paso de parámetros a la función llamada, así que para tales casos tendrás que recurrir a rodeos como usar variables globales y similares. Sin embargo, si no necesitas dar soporte a Internet Explorer 9 e inferiores, podrás usar la versión más reciente de setTimeout() con soporte para paso de parámetros (en las referencias del final tienes más detalles). Su cabecera es:
setTimeout(func, retraso, param1, param2, ...) y puedes usarla de la siguiente forma:
function saludo(nombre){
  alert('Bienvenido ' + nombre);
}
setTimeout(saludo, 2000, usuario); 
Como has podido intuir, setTimeout() sólo se ejecuta una vez. ¿Qué pasa si queremos ejecutar de forma reiterada una función? Aquí entra en escena setInterval().

setInterval(func, x)

Ejecuta el código func cada x milisegundos. Parámetros:
  • func: función anónima, nombre de una función o variable que apunta a una función
  • x: el número de milisegundos de intervalo entre ejecuciones
Soporte: Todos los navegadores (desde IE 4)
Veamos cómo ejecutaríamos el ejemplo de antes cada 3 segundos:
<script type="application/javascript">

function saludo(){
  alert('Bienvenido');
}

setInterval(saludo, 3000);

</script>

Como ves, su uso es similar a setTimeout, y al igual que este, dispone de una versión más actual con soporte para paso de parámetros. Puedes ver más información siguiendo los enlaces de las referencias.


Referencias: setTimeout en MDN, setInterval en MDN, JavaScript Timers en MDN

Cómo insertar y obtener el ID en una única consulta con MySQL y PHP

Cuando trabajamos con PHP y MySQL, a menudo necesitarás insertar un elemento nuevo en una tabla y obtener su ID para trabajar con él en tu script de PHP. Por tanto, el esquema del script sería:
  • Operaciones en PHP
  • Inserción de elemento en la BD
  • Recuperación del ID insertado
  • Más operaciones en PHP
Supongamos que tenemos una tabla de usuarios con los siguientes campos:

/* Tabla BD:
 *   usuario
 * Campos: 
 *   id     - int, auto_increment
 *   nombre - varchar
 *   edad   - int
 */

La solución más inmediata (y errónea) sería:
$bd = new mysqli(...);
$bd->query('INSERT INTO usuario (nombre, edad) VALUES ("Fran", 23)');
$result = $bd->query('SELECT MAX(id) FROM usuario');
$id = $result->fetch_assoc();

Pero esto es un terrible error que no puedes cometer nunca, no solo por la pérdida de rendimiento al realizar dos consultas, sino que también porque la segunda consulta no siempre se ejecutará inmediatamente después de la primera. Si piensas que al estar una después de otra se ejecutarán las dos en ese orden, permiteme hacerte pensar en la concurrencia de usuarios. Si dos usuarios entran a la vez en esta parte del script, puede ser que se ejecuten primero los dos INSERT y después los dos SELECT, devolviendo a ambos el mismo id. ¿Qué podemos hacer entonces? Existen varias opciones:
  • Bloquear la tabla al entrar al script. No recomendado por la pérdida de rendimiento
  • Usar un procedimiento almacenado (PROCEDURE). 
  • Usar insert_id de PHP
Si tenemos disponible la extensión mysqli de PHP (algo normal), bastará con acceder al atributo insert_id. Este atributo lo actualiza el servidor de forma automática cada vez que se hace una inserción y, lo que es mejor, con control de concurrencia.

Veamos un ejemplo usando la extensión mysqli de PHP con orientación a objetos:
$bd = new mysqli(...);
$bd->query('INSERT INTO usuario (nombre, edad) VALUES ("Fran", 23)');
$id = $bd->insert_id);
$bd->close();

Si estás usando mysqli por procedimientos, entonces deberías llamar a la función mysqli_insert_id():
$link = mysqli_connect(...);
mysqli_query($link, $query);
$id = mysqli_insert_id($link);
mysqli_close($link);

Eso es todo.

Detalles técnicos:
Lenguajes: PHP5, MySQL5
Referencias: extensión mysqli, insert_id

VisuExplorer. Un visualizador de la Web Semántica

He aquí mi proyecto final de grado (PFG). Es una aplicación web que, apoyada en la Web Semántica, construye redes en las que se muestran las relaciones que unen a las entidades almacenadas.
Básicamente, la aplicación tiene una base de datos de personajes históricos de la informática que ha sido creada a partir de la información semántica que proporciona DBpedia (que a su vez extrae los datos estructurados de Wikipedia). Con estos datos, un usuario puede buscar dichos personajes históricos y ver qué relaciones les unen con otros personajes de la base de datos. De todas formas, en la sección de enlaces hay un enlace para probar la aplicación de forma inmediata.
Visualización que se puede crear con la aplicación


La aplicación ha sido desarrollada sobre cinco pilares básicos:
  • Web Semántica
  • AJAX
  • Teoría de redes
  • Sistemas de Recuperación de Información con Retroalimentación de Relevancia
  • Algoritmo Beam Search para la búsqueda de caminos
Desde el punto de vista de la interfaz, se han utilizado las siguientes tecnologías:
  • HTML5, CSS3 y AJAX para mejorar la interactividad con el usuario.
  • Biblioteca Bootstrap para generar una interfaz con diseño adaptable.
  • Biblioteca D3.js para gestionar el algoritmo de visualización de redes.
Interfaz completa de la aplicación (clic para ampliar)

Detalles técnicos:

Sistema Web de Video Docencia

Para la asignatura de Programación Web, se nos propuso una lista de proyectos para que realizara cada alumno uno. Yo opté por el Sistema Libre de Video Docencia (SiLViDo), una aplicación web similar a las conocidas plataformas de cursos masivos online como Coursera o Udacity pero teniendo en cuenta que apenas se disponen de 2-3 meses para realizar el proyecto, por lo que las características son limitadas.
Quise que el sistema que iba a diseñar tuviera las siguientes premisas:
  • Interfaz simple e intuitiva
  • Coherencia entre secciones, es decir, que las distintas secciones tuviesen un aspecto similar
  • Uso de AJAX para mejorar la interactividad
A continuación se presentan algunas capturas de pantalla de la aplicación.


 




Finalmente, mencionar que es posible probar la aplicación (disponible en la sección de enlaces) haciendo uso de los siguientes datos:
  • Administrador (usuario/contraseña):  ejercicio_pw pass_ejercicio_pw
  • Profesor (usuario/contraseña): profesor profesor
  • Alumno (usuario/contraseña): alumno alumno

Detalles técnicos:

Panoramas con Visión por Computador

Como proyecto final cuando estudié Visión por Computador, mi compañero y yo decidimos trabajar en la creación de panoramas lineales. La proyección sería en superficies cilíndricas para no perder la perspectiva y para fusionar las imágenes usaríamos el algoritmo de Burt-Adelson. Trabajaríamos con la biblioteca OpenCV aunque no teníamos permitido usar el módulo Stitching, así que todo lo implementamos nosotros, salvo para la generación de puntos destacados con SIFT.

Un ejemplo de los resultados que obtuvimos es este panorama compuesto de 24 imágenes en el que no es fácil encontrar los puntos de unión:
Clic para ampliar

 O este otro panorama de 12 imágenes:
Clic para ampliar

Aunque en la documentación adjunta es posible leer con detalle el enfoque teórico de nuestra implementación, comentaré aquí que, para la generación de los panoramas, básicamente se ha seguido el siguiente esquema:
  1. Paso de las imágenes originales a coordenadas cilíndricas
  2. Selección de puntos destacados usando SIFT
  3. Cálculo de las homografías
  4. Selección de las áreas a fusionar
  5. Mezcla piramidal de las áreas de fusión


Detalles técnicos:

Agradecimientos a Chaman Singh Verma y Mon-Ju por publicar las imágenes originales para los panoramas en http://pages.cs.wisc.edu/~csverma/CS766_09/ImageMosaic/DataSet/Set7/BlendImages/

Analizador Apache

Sencillo programa en C++ para poner en práctica el uso de las expresiones regulares junto con Lex. El programa recibe como entrada el log por defecto de un servidor web Apache y lo procesa para devolver al usuario las estadísticas que solicite.

El programa se utiliza desde la consola y la interfaz se muestra en la siguiente captura de pantalla.


 Detalles técnicos:
  • Lenguaje: C++
  • Plataforma: GNU/Linux 
  • Paradigma: Funcional
  • Aprendizaje de: Expresiones regulares, procesamiento de ficheros, Lex
  • Enlaces: código fuente, manual de usuario
  • Año: 2013