Sustituir alertas del navegador con jQuery UI

Antes que nada decir que reemplazar la funcionalidad de las alertas del navegador con código JavaScript nunca es 100 % compatible, por citar un (y el más importante) ejemplo la ejecución del script no se detiene cuando utilizas librerías JavaScript para sustituir alertas.

Teniendo en cuenta lo anterior existen 2 opciones para embellecerlas con jQuery, utilizar librerías externas o utilizar los propios cuadros de diálogos de jQuery UI. Si trabajas con esta última librería sería absurdo utilizar otro plugin para recargar aún más nuestro código. Además que muchas de las librerías (como la de jAlert) no están actualizadas con las últimas versiones de jQuery lo que nos obligaría a utilizar la librería extra de migración.

Pero hacerlo con jQuery UI no es tan trivial como parece, hay que tener en cuenta un par de cosas importantes:

  1. auto foco, los cuadros de diálogo de jQuery UI tienen el foco puesto automáticamente en el primer elemento enfocable de nuestro html, lo cual puede que no sea nada deseable, esto es fácilmente corregible agregando la siguiente línea al html del cuadro de dialogo: <input autofocus type='hidden' />.
  2. el centrado automático, para centrar automáticamente la ventana de un cuadro de diálogo jQuery utiliza la posición del objeto padre que hace la llamada, nuestros mensajes de alerta carecen de estos padres con lo cual centrar el mensaje cuando la ventana tiene un scroll activo no muestra los resultados esperados, mi solución ha sido ubicar estos mensajes centrados horizontalmente pero en la parte superior de la ventana, position: {my: "top", at: "center top", of: window}.

Aquí os dejo el código de los 3 mensajes de alerta (alert, prompt y confirm) de esta forma podríamos sustituir los que vienen por defecto con unos más visuales y acordes a nuestro diseño.

$.extend({
	prompt: function(text, value, title, callback) {
		text = text || '';
		title = title || 'Input';
		value = value || '';
		$('<div />')
	        .attr({title: title})
	        .html("<p>" + text + "</p><input type='text' id='input-dialog-form' value='" + value + "' />")
	        .dialog({
	        	buttons: {
	            	"Ok": function(){
	            		if(callback){
	            			if(callback($('#input-dialog-form').val())){
	            				$(this).dialog('close');
	            			}
	            		}
	            		else{
	            			$(this).dialog('close');
	            		}
	            	},
	            	"Cancel": function(){
	            		if(callback){
	            			callback(false);
	            		}
	            		$(this).dialog('close');
	            	}
	            },
	            close: function(event, ui){
	            	$(this).remove(); 
	            },
	            draggable: false,
	            modal: true,
	            resizable: false,
	            width: 'auto',
	            position: {my: "top", at: "center top", of: window}
	        });
    },
    alert: function(message, title, callback) {
		title = title || 'Alert';
		$('<div />')
	        .attr({
	        	title: title
	        })
	        .html("<input autofocus type='hidden' /><div class='mensajes-informativos'>" + message + "</div>")
	        .dialog({
	        	buttons: {
	            	"Ok": function(){
	            		$(this).dialog('close');
	            		if(callback){
	            			callback();
	            		}
	            	}
	            },
	            draggable: false,
	            modal: true,
	            resizable: false,
	            width: 'auto',
	            position: {my: "top", at: "center top", of: window}
	        });
    },
    confirm: function(message, title, callback) {
    	title = title || 'Confirm';
    	$('<div />')
	        .attr({
	        	title: title
	        })
	        .html("<p class='mensajes-informativos'>" + message + "</p>")
	        .dialog({
	        	buttons: {
	            	"Yes": function() {
	            		$(this).dialog("close");
	            		if(callback){
	            			callback(true);
	            		}
	                },
	                "No": function() {
	                	$(this).dialog("close");
	                	if(callback){
	            			callback(false);
	            		}
	                }
	            },
	            draggable: false,
	            modal: true,
	            resizable: false,
	            width: 'auto',
	            position: {my: "top", at: "center top", of: window}
	        });
    }
});

Con esto ya podremos reemplazar los mensajes de alerta con jQuery sin necesidad de ninguna librería externa salvo el propio jQuery y jQuery UI.

Comentarios