Julio 17

2017
InputBox

INPUT BOX

Algo que se echa mucho de menos en la web es el tipico INPUT BOX para recoger datos del usuario al pulsar sobre un boton. Para ello JAVASCRIPT nos otorga la funcion prompt() pero dependiendo del navegador tiene un formato diferente y no podemos controlar nada sobre la ventana, posicion, tamaño, color, forma... bla, bla, bla. Pero como siempre, navegando por internet podemos encontrar solicioines en JAVASCRIPT muy buenas, y yo he recogido una de ellas y os la presento aqui, con mi pequeño toque particular.

El autor es Jorge MG, que a su vez era sitado en este blog de KsesoCSS, muy bien explicado, le he dado mi toque, y a la hora de llamar a la ventana tienes directamente dos opciones, como input box o como messagebox. De esta forma, "simplificamos" un poco que opcion quieres usar.

MessageBox

A la utilidad la he llamado con en Microsost Visual Basic 6, MessageBox, y como funciones show() inputbox(), asi el que esta acostumbrado puede usarlo mas pacilmente. Para crear el objeto debemos  de pasarle un objeto de con la siguiente informacion.

config = {
                ID : 'Message',        //id de la ventana
                panel : 'panel',        //clase css para el panel
                title : 'title',        //clase css para el titulo
                close : 'close',        //clase css para el boton cerrar (X) predeterminado
                content : 'content',    //clase css para el contenido
                footer : 'footer',      //clase css para el pie
                zindex : '9999'         //posicion de la ventana
          };
Como se ve puedes personalizar el nombre de las clases a utilizar, de esta forma puedes personalizar facilmente todo el CSS que va a controlar las ventanas.  Pero el  unico parametro obligatorio seria el ID. El resto se han escrito los nombres por defecto del objeto. Luego se crea el objeto y se le pasa la configuracion, y aqui es importante tener en cuenta que hay que declararlo DESPUES de la etiqueta body.

<body>
<script type="text/javascript">
config = {
ID: 'Message-input', //id de la ventana
panel: 'panel', //clase css para el panel
title: 'title', //clase css para el titulo
close: 'close', //clase css para el boton cerrar (X) predeterminado
content: 'content', //clase css para el contenido
footer: 'footer', //clase css para el pie
zindex: '999' //posicion
};
var test = messageWindow(config);
</script>
</body>

Mostrar un mensaje

Para mostrar una simple ventana con un mensaje, llamaremos a la funcion  show(data, boton1, boton2), en la que podremos poner un maximo de dos (2) botones. Le tenemos que enviar de 1 a 3 parametros. El primero definira el titulo de la ventana, el mensaje a mostrar y el tamaño de ancho y alto de la ventana. Los otros dos son los botones, los dos son opcionales, ya que siempre se muestra el boton de cerrar (X) en la esquina superior derecha.

data = { title: 'Ventana modal', width: 400, height: 40, content: 'Mensaje de la ventana' };
boton1 = ['Aceptar', function () { alert('Has pulsado aceptar.'); }];
boton2 = ['Cancelar', '' }];
test.show(data, boton1, boton2);
Como se puede observar en la definicion del boton podemos pasarle una funcion a ejecutar despues de presionar el boton correspondiente.

Message Box

Mostrar un input box

Si lo que necesitamos es que el usuario entre algun tipo de informacion, llamaremos a la funcion inputbox(data, boton, placeholder), todos los parametros son obigatorios, si no generara errores. Los dos primeros son exactamente igual que para mostrar un mensaje,  con la salvedad de que la funcion asignada al boton va a recibir como parametro lo que esta escrito en la caja de texto. El ultimo parametro es el texto que se va a mostrar en el cuadreo de texto como ayuda.

data = { title: 'Ventana modal', width: 400, height: 40 };
boton = ['Aceptar', function (input) { alert('Bienvenido, ' + input); }];
test.inputbox(data, boton, 'escribre tu nombre');


InputBox

Consideraciones

El objeto data es un JSON, que podria dejarte en blanco, o nulo, la ventana se creara con los valores por defecto. Sus parametros son:
  1. title: Titulo de la ventana, si no se suministra utilizara el nombre pasado para crear la ventana.
  2. content: Contenido de la ventana. Se puede pasar todo lo que se quiera en formato HTML, incluidos los IFRAME, o imagenes.
  3. width: el ancho en pixels.
  4. height: el alto en vh.
Para crear los botones es un array de dos dimensiones. la primera define el texto a mostrar y el segundo la funcion a ejecutar.
Por ultimo hay que hacer referencia al archivo JAVASCRIPT que podeis descargar en este blog, o hacer referencia directamente a mi servidor seguro

<script src="https://community-mall.com/js/messagewindow.js"></script>

Ejemplo de uso

<body>
<script src="https://community-mall.com/js/messagewindow.js"></script>
<script type="text/javascript">
config = {
ID: 'Message-input'
};
var test = messageWindow(config);
function TomaDatos() {
data = { title: 'Dime tu nombre', width: 400, height: 40 };
boton = ['Aceptar', function (input) { alert('Bienvenido, ' + input); }];
test.inputbox(data, boton, 'escribre tu nombre');
}
</script>
<a href="javascript:void(0)" onclick="TomaDatos();">Dime quien eres</a>
</body>

Todo el codigo para que lo disfruten

Como siempre si alguien tiene alguna idea para mejorar es libre de comentar. Si lo que quieren es criticar, tambien es bien venido.

/**
* MessageWindow.js v1.0.0
* http://www.drualcman.es
*
* Autor: Jorge MG
* CSS: Kseso
* Source Blog: https://escss.blogspot.com/2016/09/ventana-modal-javascript-puro.html
* Modificado por: Sergi Ortiz Gomez (drualcman@msn.com)
* Licencia: Creative Commons Reconocimiento-NoComercial-CompartirIgual
*/

/* Create Object */
(function (root, factory) {
if (typeof exports === 'object') {
/* CommonJS*/
factory(exports);
} else if (typeof define === 'function' && define.amd) {
/* AMD. Register as an anonymous module.*/
define(['exports'], factory);
} else {
/* Browser globals*/
factory(root);
}
}
/* Create a MessageWindow */
(this, function (exports) {
/**
* GLOBALS VARIABLES
*/
var VERSION = '1.0.0';
var CONFIG; /* configure CSS and others */

/* Create default Object */
function MessageWindow(config) { /*https://escss.blogspot.com/2016/09/ventana-modal-javascript-puro.html */
//get the configuration for the defaul window
if (config === undefined || config === '') {
CONFIG = _MessageConfig(); /* Default Config */
} else {
CONFIG = _mergeOptions(_MessageConfig(), config);
}
CrearVentana();
}

/**
* Crear la ventana
*/
function CrearVentana() {
if (document.getElementById(CONFIG.ID) == null) {
//crear la ventana ya que no existe
var d = document.createElement("div");
//d.className = CONFIG.ID; // la clase para estilizarla vía CSS se llamara igual que la ventana
d.id = CONFIG.ID;
// creamos el panel interior
var p = document.createElement("div");
p.className = CONFIG.panel;
// creamos los componentes de la cabecera: título y botón de cerrar
var t = document.createElement("div");
t.className = CONFIG.title;
var cl = document.createElement("div");
cl.className = CONFIG.close;
cl.innerHTML = '×';
// cerramos y eliminamos la modal al pulsar el botón X
cl.addEventListener('click', function (ev) {
ev.preventDefault();
// cerramos y vaciamos la modal al cerrar la ventana
var dTop = this.parentNode.parentNode;
dTop.classList.remove("visible");
dTop.querySelector(".panel .content").innerHTML = '';
});
// creamos la caja donde se mostrará el contenido
var ct = document.createElement("div");
ct.className = CONFIG.content;
// también añadimos un pie, para añadir los posibles botones
var f = document.createElement("div");
f.className = CONFIG.footer;
/* finalmente, añadimos "t", "cl", "ct" y "f"
(título, botón cerrar, div contenido y div footer)
a "p" (panel interior), éste lo añadimos a "d"
(div principal, para oscurecer el fondo), y "d"
lo añadimos al body de la página */
//p.appendChild(s); //style
p.appendChild(t); //title
p.appendChild(cl); //close
p.appendChild(ct); //content
p.appendChild(f); //footer
d.innerHTML = Css(); //style
d.appendChild(p); //panel
document.body.appendChild(d); //MessageWindow
}
}

/* Default Config CSS */
function _MessageConfig() {
return {
ID : 'Message-', //id de la ventana
panel : 'panel', //clase css para el panel
title : 'title', //clase css para el titulo
close : 'close', //clase css para el boton cerrar (X) predeterminado
content : 'content', //clase css para el contenido
footer : 'footer', //clase css para el pie
zindex : '9999' //posicion de la ventana
};
};

/* Default CSS */
function Css() {
var css = "";
css += "<style>";
css +="#"+ CONFIG.ID + '{font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;color: #224;text-align: center;font-variant: small-caps;position: fixed; margin: auto; top:0;left:0;right:0;bottom:0; background: rgba(34,34,68,.8); box-sizing: content-box; visibility: hidden; opacity: 0; transition: all .12s; z-index: ' + CONFIG.zindex + ';}' ;
css += "#"+ CONFIG.ID + " h1 {font-weight: 400;}";
css += "#"+ CONFIG.ID + " button {border: 3px solid #224;background: #fff;padding: 1rem;margin: 1rem .5rem;font-size: 1.2rem;font-variant: small-caps;transition: all .5s;cursor: pointer;box-shadow: inset 0 0 0 rgba(0,0,0,1);}";
css += "#"+ CONFIG.ID + " button:hover {color: #fff;box-shadow: inset 0 0 0 10rem rgba(34, 34, 65, .68);}";
css += "#"+ CONFIG.ID + ".visible {visibility: visible; opacity: 1;} ";
css += "#"+ CONFIG.ID + " * {box-sizing: inherit} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " {position: absolute; margin: auto;top:0;left:0;right:0;bottom:0;max-width: 600px; max-height: 70vh;background: #0ebeff; border-radius: 10px;color: #000; padding: 50px 0;transform: translateY(-25%);transition: all .12s;} ";
css += "#"+ CONFIG.ID + ".nofooter ." + CONFIG.panel + " {padding: 50px 0 0 0;} ";
css += "#"+ CONFIG.ID + ".visible ." + CONFIG.panel + " {transform: none;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " .close {position: absolute; top: .25em; right: .75em;cursor: pointer; font-size: 25px;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.title + " {position: absolute; top: 0;width: 100%; height: 50px;line-height: 50px;background: orange;font-weight: bolder; padding: 0 2em;box-shadow: 2px 0 10px rgba(0,0,0,.6);border-radius: 10px 10px 0 0;box-sizing: border-box;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " ." + CONFIG.content + " {max-height: 100%; overflow: auto;padding: 1em; box-sizing: border-box;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " ." + CONFIG.content + " iframe:only-child {border: 0; width: 100%;height: 100%; height: 80vh;min-height: 200px;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " ." + CONFIG.content + " img:only-child {width: 100%; max-width: 100%;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " ." + CONFIG.footer + " {position: absolute; bottom: 0;width: 100%; background: orange;font-weight: bolder; padding: 0 .5em;box-shadow: 2px 0 10px rgba(0,0,0,.6);border-radius: 0 0 10px 10px;box-sizing: border-box;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;text-align: right;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " ." + CONFIG.footer + " .action {border-radius: 10px; color: #000;background: #fff; border: 0;min-width: 80px; min-height: 35px;font-weight: bold; cursor: pointer;margin-left: 20px;transition: all .12s;} ";
css += "#"+ CONFIG.ID + " ." + CONFIG.panel + " ." + CONFIG.footer + " .action:hover {box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.6);}";
css += "</style>";
return css;
};

/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
*
* @param {object} obj1 origin
* @param {object} obj2 new object to merge
* @returns {object} obj3 a new object based on obj1 and obj2
*/
function _mergeOptions(obj1, obj2) {
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname1 in obj2) { obj3[attrname1] = obj2[attrname1]; }
return obj3;
};

/* Create the global object */
var messageWindow = function (_config) {
if (typeof (_config) === undefined) {
/* need params show help to use */
return new MessageWindow();
} else {
/* Run With all parameters sended */
return new MessageWindow(_config);
}
};

/**
* Mostrar una ventana con 2 botones maximo
* @param {JSON} data {title: 'Titulo', width: en px, height: en vh, content: 'Contenido'}
* @param {Array} ok Array ['Captoin', function ([varble]) { }]
* @param {stirng} input Texto para el placehover del input box
*/
function InputBox(data, ok, input) {
CrearVentana();
data = data || {}; // si no existe data, creamos un objeto vacío para evitar posteriores errores
// guardamos cada componente en una variable
var mod = document.getElementById(CONFIG.ID),
p=mod.querySelector("." + CONFIG.panel),
t=mod.querySelector("." + CONFIG.panel + " ." + CONFIG.title),
ct=mod.querySelector("." + CONFIG.panel + " ." + CONFIG.content),
f = mod.querySelector("." + CONFIG.panel + " ." + CONFIG.footer);
mod.className = "visible";
if (f==null) {
// puede ocurrir que el footer no exista, así que lo volvemos a crear
mod.classList.remove("nofooter");
var f=document.createElement("div");
f.className="footer";
p.appendChild(f);
}
// rellenamos los datos
t.innerHTML=data.title || CONFIG.ID;
ct.innerHTML=data.content || '';
f.innerHTML='';
// comprobamos que el número es válido antes de añadirlo
if (!isNaN(data.width)) p.style.maxWidth=data.width+'px';
if (!isNaN(data.height)) p.style.maxHeight=data.height+'vh';
// si es necesario, creamos el botón "Aceptar"
if (ok && ok.length>1) {
// la variable "param" se usará para devolver el valor del input
// si no hubiera input, el valor será null
var param={value:null};
// si es necesario, creamos un párrafo nuevo con su input
var ph=document.createElement("p");
ph.className="action";
var txt=document.createElement("input");
txt.className="action";
txt.setAttribute("placeholder",input);
txt.addEventListener('keydown',function(ev) {
// pulsar "enter" es equivalente a pulsar "aceptar"
if (ev.keyCode==13 || ev.key=="Enter") {
ev.preventDefault();
mod.classList.remove("visible");
ok[1](param.value);
}
});
// añadimos el input al párrafo, y éste al contenido
ph.appendChild(txt);
ct.appendChild(ph);
// guardamos la referencia al input
param=ct.querySelector("p.action > input.action");
/* ponemos el foco al input, pero esperamos
unos milisegundos para que se genere */
setTimeout(function(){
param.focus();
},100);
// creamos el botón OK
var bOk=document.createElement("button");
bOk.className="action";
bOk.innerHTML=ok[0];
bOk.addEventListener('click',function(ev){
/* al pulsar en él, se cierra la ventana
y se ejecuta la función indicada, devolviendo
el valor del input (si existe) o null */
ev.preventDefault();
mod.classList.remove("visible");
ok[1](param.value);
});
// añadimos el botón al footer
f.appendChild(bOk);
}
}

/**
* Mostrar una ventana con 2 botones maximo
* @param {JSON} data {title: 'Titulo', width: en px, height: en vh, content: 'Contenido'}
* @param {Array} ok Array ['Captoin', function ([varble]) { }]
* @param {Array} cancel Array ['Captoin', function ([varble]) { }]
*/
function MessageBox(data, ok, cancel) {
CrearVentana();
data = data || {}; // si no existe data, creamos un objeto vacío para evitar posteriores errores
// guardamos cada componente en una variable
var mod = document.getElementById(CONFIG.ID),
p=mod.querySelector("." + CONFIG.panel),
t=mod.querySelector("." + CONFIG.panel + " ." + CONFIG.title),
ct=mod.querySelector("." + CONFIG.panel + " ." + CONFIG.content),
f = mod.querySelector("." + CONFIG.panel + " ." + CONFIG.footer);
mod.className = "visible";
if (f==null) {
// puede ocurrir que el footer no exista, así que lo volvemos a crear
mod.classList.remove("nofooter");
var f=document.createElement("div");
f.className="footer";
p.appendChild(f);
}
// rellenamos los datos
t.innerHTML=data.title || CONFIG.ID;
ct.innerHTML=data.content || '';
f.innerHTML='';
// comprobamos que el número es válido antes de añadirlo
if (!isNaN(data.width)) p.style.maxWidth=data.width+'px';
if (!isNaN(data.height)) p.style.maxHeight = data.height + 'vh';
var param = { value: null };
// si es necesario, creamos el botón "Aceptar"
if (ok && ok.length>1) {
// creamos el botón OK
var bOk=document.createElement("button");
bOk.className="action";
bOk.innerHTML=ok[0];
bOk.addEventListener('click',function(ev){
/* al pulsar en él, se cierra la ventana
y se ejecuta la función indicada, devolviendo
el valor del input (si existe) o null */
ev.preventDefault();
mod.classList.remove("visible");
ok[1](param.value);
});
// añadimos el botón al footer
f.appendChild(bOk);
}
// hacemos lo mismo con el botón Cancelar, si existe
if (cancel && cancel.length>1) {
var bCancel=document.createElement("button");
bCancel.className="action";
bCancel.innerHTML=cancel[0];
bCancel.addEventListener('click', function (ev) {
/* al pulsar en él, se cierra la ventana
y se ejecuta la función indicada, devolviendo
el valor del input (si existe) o null */
ev.preventDefault();
mod.classList.remove("visible");
cancel[1](param.value);
});
f.appendChild(bCancel);
}
// si no hay ningún botón, se elimina el footer
if (f.innerHTML=='') {
p.removeChild(f);
mod.classList.add("nofooter");
}
/* esperamos unos milisegundos para que se genere,
y añadimos la clase .visible para mostrarla desde CSS */
setTimeout(function(){
mod.classList.add("visible");
},50);
}

/**
* Eliminar la sesion
*/
function Eliminar() {
var mod = document.getElementById(CONFIG.ID);
mod.classList.remove("visible");
}

/**
* Current MessageWindow version
*
* @property version
* @type String
*/
messageWindow.version = VERSION;

/*Prototype*/
messageWindow.fn = MessageWindow.prototype = {
clone: function () {
return new MessageWindow(CONFIG);
},
inputbox: function (data, ok, input) {
InputBox.call(this, data, ok, input);
return this;
},
show: function (data, ok, cancel) {
MessageBox.call(this, data, ok, cancel);
return this;
},
remove: function () {
Eliminar();
return this;
},
version: function () {
return VERSION;
}
};

exports.messageWindow = messageWindow;
return messageWindow;
})
);

Happy coding

#javascript #HTML #ASP

2 Comentarios

  • Gracias Jorge MG por tu comprension, perdon por el error, fue el copia pega de otras cosas. Ya lo he cambiado, desde que vi en Facebook el comentario de Kseso. Mil disculpas.

      Jorge MG
      Wednesday, July 19, 2017 7:57 PM

    Hola, soy el autor original del script, publicado en https://escss.blogspot.com/2016/09/ventana-modal-javascript-puro.html

    Agradecería que, en lugar de "Copyright (C) 2017 Sergi Ortiz Gomez" añadieras la autoría completa del código. Por mi parte, la licencia del script es Creative Commons Reconocimiento-NoComercial-CompartirIgual (https://creativecommons.org/licenses/by-nc-sa/4.0/deed.es_ES), es decir, que al remezclarlo tienes que mantener la misma licencia, y no un copyright.

    Un saludo.

Escribir un comentario

1 + 4 =

Message Box InputBox


Archivo