Neuralpin Logo

Ventanas modales personalizadas

Como programar e implementar nuestros propios alert() y confirm() con Javascript puro

Tipos de Alojamiento web

Ver demo Descargar código

Una ventana modal (modal window) o cuadro de dialogo (dialog box) es el elemento de la interfaz de usuario que usamos cuando queremos centrar la atención del usuario en un elemento en particular que esta ligado a alguna acción en concreto, este elemento se situara por encima del demás contenido.

Por otro lado un lightbox es el efecto de oscurecer todo el contenido en nuestra interfaz a excepción de un único elemento que se busca destacar por sobre las demás cosas.

Aunque una ventana modal no tiene que ir siempre acompañada del efecto lightbox en esta ocasión si que usaremos ambas cosas.

Maquetando la estructura base

Antes de ponernos a generar código HTML desde Javascript nos viene bien primero escribir a mano la estructura para tenerla de referéncia.

<div class="liwindow-container">
<div class="liwindow-card">
<div class="liwindow-header">
<h4>Estas a punto de eliminar un archivo</h4>
<button type="button" class="liwindow-close">×</button>
</div>
<div class="liwindow-body">Realmente deseas continuar?</div>
<div class="liwindow-footer">
<button type="button" class="liwindow-btn liwindow-cancel">Cancelar</button>
<button type="button" class="liwindow-btn liwindow-acept">Aceptar</button>
</div>
</div>
</div>

Usaremos un contenedor general (.liwindow-container) que sera el que oculte todo el demás contenido de la web mostrandose semiopaco.

Dentro pondremos el cuadro (.liwindow-card) que contendrá los elementos de nuestra ventana modal.

Para el caso de las ventanas tipo confirm() usaremos un header (.liwindow-header) donde pondremos el titulo de la ventana modal y el botón de cierre (.liwindow-close).

Después viene el contenedor del cuerpo de la ventana (.liwindow-body) y por ultimo el pie (.liwindow-footer) donde pondremos los botones (.liwindow-btn) para aceptar (.liwindow-acept) o cancelar (.liwindow-cancel).

Aplicando los estilos

/* -- liwindow -- */
.liwindow-container *, .liwindow-container *::after, .liwindow-container *::before{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.liwindow-container{
position: fixed;
top: 0;
left: 0;
background: rgba(0,0,0,0.5);
width: 100%;
height: 100%;
z-index: 200;
}
/* -- liwindow Modal Dialog -- */
.liwindow-card{
margin: 0 auto;
margin-top: 40px;
width: 500px;
max-width: 100%;
box-shadow: 0px 0px 25px -5px #333;
}
.liwindow-header, .liwindow-footer, .liwindow-body{
background-color: #fff;
}
.liwindow-header{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.liwindow-close{
padding: 20px;
display: inline-block;
font-size: 1.33rem;
color: #333;
font-weight: bold;
background-color: transparent;
border: none;
transition: 0.3s all;
}
.liwindow-close:hover, .liwindow-close:focus{
color: #7C4DFF;
background-color: #f3f3f3;
}
.liwindow-close:active{
color: #7C4DFF;
transform: translate(-3px, -3px);
transform: scale(0.9);
}
.liwindow-close:focus{
outline: 1px solid #00BCD4;
}
.liwindow-body{
padding: 20px;
color: #333;
font-size: 18px;
}
.liwindow-header h4{
color: #333;
padding: 20px;
display: inline-block;
font-size: 25px;
font-weight: bold;
}
.liwindow-footer{
text-align: right;
}
.liwindow-btn{
padding: 20px;
background-color: transparent;
border: none;
color: #9c27b0;
text-transform: uppercase;
font-size: 15px;
transition: 0.3s all;
}
.liwindow-btn:hover, .liwindow-btn:focus{
color: #7C4DFF;
background-color: #f3f3f3;
}
.liwindow-btn:active{
color: #7C4DFF;
transform: translate(-3px, -3px);
transform: scale(0.9);
}
.liwindow-btn:focus{
outline: 1px solid #00BCD4;
}
.liwindow-hide{
display: none;
}

Aplicando estos estilos CSS anteriores a nuestra estructura HTML tendríamos la siguiente apariencia:

Modal window confirm

Definiendo las clases y métodos

/* -- Clase principal para el modal window -- */
class liwindow {
constructor(html)
/* Metodo para abrir lightbox */
show()
/* Metodo para cerrar lightbox*/
hide()
/* Metodo para agregar contenido al lightbox*/
setContent()
/* Metodo para remover el lightbox y su contenido del html*/
remove()
}
/* -- Alert Modal Window -- */
class lialert extends liwindow {
}
/* -- Confirm Modal Window -- */
class liconfirm extends liwindow {
}

Partiremos de una clase general con los métodos necesarios para el funcionamiento de nuestras ventanas modales, crearemos una clase heredera por cada elemento con el efecto lightbox que deseemos. En este caso una clase para nuestros custom alert() y otra para nuestros custom confirm().

Lógica de la clase principal

/* -- Clase para lightbox y modal dialogs -- */
class liwindow {
constructor(html) {
/* Creamos el contenedor principal del lightbox */
this.container = document.createElement("div");
this.container.setAttribute("class", "liwindow-container liwindow-hide");
this.container.addEventListener("click", this.hide);
document.body.appendChild(this.container);

/* Añadimos el html proporcionado */
if (html != null) this.setContent(html);
}

/* Metodo para abrir lightbox */
show = () => {
this.container.classList.remove("liwindow-hide");
document.body.style.overflow = "hidden";
};

/* Metodo para cerrar lightbox */
hide = () => {
this.container.classList.add("liwindow-hide");
document.body.style.overflow = "auto";
};

/* Metodo para agregar contenido al lightbox */
setContent = (cont) => {
if (typeof cont == "string") {
this.container.innerHTML = cont;
this.container.firstChild.addEventListener("click", function (e) {
e.stopPropagation();
});
} else {
cont.addEventListener("click", function (e) {
e.stopPropagation();
});
this.container.appendChild(cont);
}
};

/* Metodo para remover el lightbox y su contenido del html */
remove = () => document.body.removeChild(this.container);
}
Nota: En lugar de métodos de clase se están usando arrow functions asignadas a propiedades de clase, funcionaran igual que métodos normales, con el añadido de que cualquier uso de this dentro de ese contexto siempre hace referencia a la clase, lo que es realmente necesario para poder llamar las propiedades de nuestra clase desde los addEventListener que usaremos.