En el siguiente artículo voy a sobreescribir la función javascript window.alert() para mostrar una ventana de dialogo mas atractiva visualmente. Para ello voy a utilizar la librería jQuery, los awesome buttons de Zurb.com y me voy a basar en el diseño de los dialogos de Facebook.

Resultado final

Nota: En el siguiente tutorial voy a utilizar un navegador web de verdad y voy a utilizar propiedades CSS3, por lo el diseño final no va a ser idéntico en Internet Explorer 6,7,8. En caso de querer compatibilidad con estas versiones del navegador bastaría con crear una hoja de estilos especifica, sin embargo en este tutorial no se va a contemplar esta opción.

HTML

El código HTML del diálogo se generará mediante javascript y se insertará al final de la etiqueta body.

El código HTML será el siguiente:

<div id="dialog">
  <div id="dialog-wrapper">

    <h1>Titulo</h1>

    <div id="dialog-content">
      <p>Content</p>
    </div>

    <div id="dialog-content">
      <!-- Botón CSS3 -->
      <a class="awesome small orange">Aceptar</a>
    </div>

  </div>
</div>

CSS

El elemento con id #dialog servirá para posicionar el dialogo en el centro de la ventana respecto al eje Y. Así pues tendrá posición absoluta y definirá la propiedad top con un valor inicial de 150px.

#dialog{
  position: absolute;
  top: 150px;
  width: 100%;
}

El elemento con id #dialog-wrapper servirá para centrar el dialogo a lo ancho, establecerá su ancho y mostrará el borde semitrasparente.

Es importante indicar que este elemento no puede tener un background-color ya que este color quedaría por debajo del borde transparente y entonces no se apreciaría el efecto.

#dialog-wrapper{
  border: 10px solid rgba(150, 150, 150, 0.7);
  border-radius: 10px;
  -webkit-border-radius: 10px;
  -mox-border-radius: 10px;
  margin: 0 auto;
  width: 500px;
}

Los siguientes elementos h1, #dialog-content y #dialog-footer no tienen mucho que resaltar.

#dialog h1{
  background-color: #f60;
  border: 1px solid #c30;
  border-bottom: 0;
  color: white;  
  padding: 5px 10px;
}

#dialog-content{
  background-color: white;
  border: 1px solid #666;
  border-width: 0 1px 1px;
  padding: 10px;
}

#dialog-content p{
  margin-bottom: 10px;
}

#dialog-footer{
  background: #ccc;
  border: 1px solid #666;
  border-top: 0;
  padding: 10px;
  text-align: right;  
}

jQuery

Llega el momento hacerlo funcionar todo. La mayor parte del trabajo va a ser la creación del HTML anterior.

La estructura será la siguiente:

(function($){
  // Uso: $(document).dialog("Texto");
  //      $(document).dialog({title: "Titulo", content: "Content"});
  $.fn.dialog = function(data){
    // Inicialización de los datos a mostrar

    // Determinar la posición del dialogo

    // Creación del dialogo
  }
});

Primero, debemos comprobar el tipo de objeto recibido como parámetro. Si éste es una cadena entonces lo usaremos como contenido del dialogo. Si por el contrario recibimos un objeto con las propiedades title y content utilizaremos esta información para mostrar el dialogo.

var title, content;
if(data && data.title){ title = data.title; }else{ title = "Javascript alert"; }
if(data && data.content){ content = data.content; }else{ content = data; }

Obtener la posición donde se mostrará el dialog es sencilla. lo vamos a situar siempre a 150 px de la parte superior de la ventana, para ello tenemos que tener el cuenta el scroll de la página:

var currentTop = $(document).scrollTop();

La creación del dialogo tendrá en cuenta este valor:

var $dialog = $('<div>', {id: 'dialog', css:{top: currentTop + 150}}).prependTo('body');

var $title = $('<h1>').text(title).appendTo($wrapper);
var $content = $('<div>', {id: 'dialog-content'}).html("<p>"+content+"</p>").appendTo($wrapper);
var $footer = $('<div>', {id: 'dialog-footer'}).append(
  $('<a>', {'class': 'awesome small orange'})
    .text("Aceptar")
    .click(function(){
      $dialog.fadeOut(function(){$dialog.remove()});
      return false;
    })
  ).appendTo($wrapper);

Solo destacar la función del evento click del botón aceptar. Esta función primero hace un fadeOut del dialogo y al terminar lo elimina del DOM.

A continuación lo insertamos en el DOM con un efecto fadeIn.

$dialog.hide().appendTo('body').fadeIn();

Y para terminar vamos a añadir funcinalidad extra para poder cerrar el dialogo utilizando la tecla escape o la tecla enter.

return $(this).keyup(function(evt){
  if (evt.which == 27 || evt.which == 13){
    $dialog.fadeOut(function(){$dialog.remove()});
  }
}); 

Código final

El código final es el siguiente:

(function($){
  $.fn.dialog = function(data){
    var title, content;
    if(data && data.title){ title = data.title; }else{ title = "Javascript alert"; }
    if(data && data.content){ content = data.content; }else{ content = data; }

    var currentTop = $(document).scrollTop();
    var $dialog = $('<div>', {id: 'dialog', css:{top: currentTop + 150}}).prependTo('body');

    var $wrapper = $('<div>', {id: 'dialog-wrapper'}).appendTo($dialog);
    var $title = $('<h1>').text(title).appendTo($wrapper);
    var $content = $('<div>', {id: 'dialog-content'}).html("<p>"+content+"</p>").appendTo($wrapper);
    var $footer = $('<div>', {id: 'dialog-footer'}).append(
        $('<a>', {'class': 'awesome small orange'})
          .text("Aceptar")
          .click(function(){
            $dialog.fadeOut(function(){$dialog.remove()});
            return false;
          })
      ).appendTo($wrapper);
    $dialog.hide().appendTo('body').fadeIn();

    return $(this).keyup(function(evt){
      if (evt.which == 27 || evt.which == 13){
        $dialog.fadeOut(function(){$dialog.remove()});
      }
    });
  }
})(jQuery);

Probando el dialogo y sobreescribiendo window.alert

Ahora podemos invocar este diálogo tal que así:

$(document).dialog("Texto");

La idea inicial es que este dialogo sustituya al predefinido en nuestro navegador. Esto es muy sencillo, basta con incluir lo siguiente:

window.alert = $(document).dialog;

Puedes probarlo en la página de demostración desde el inspector de webkit si estas en chrome o desde firebug si estas en firefox.

Demo