Laboratorio: control para direcciones IP
Algo que me suele gustar bastante es que cuando tengo que introducir una dirección IP en un formulario o ventana de Windows, no tenga que estar dándole al tabulador para cambiar de caja de texto. Lo mismo es aplicable cuando se trata de un serial number. Tambien suelo agradecer que hacer un copy/paste, no tenga que ir haciéndolo caja a caja.
Siempre viene bien hacernos un control para direcciones IP, que permita pegar toda la dirección ip y que se rellenen las cajas correctamente y que al pulsar el punto se mueva de caja, y la verdad es que tampoco es muy difÃcil de hacer.
Para crearnos el control, vamos a crearnos cuatro cajas de texto (<input type=”text” .. />) que tengan el mismo id, y vamos a controlar que solo se puedan pulsar números, el punto y teclas de control (CTRL+C, por ejemplo), que si escribimos 3 caracteres nos salte de caja, lo mismo que si pulsamos un punto.
Tendremos varias funciones, una de ellas que se ejecuta en el onload del body se encargará de añadir los eventos para pulsar la tecla y levantarla (onmousedown y onmouseup) para evitar que se introduzcan teclas no deseadas y para gestionar el control.
// Obtiene los elementos de la caja de texto y modifica los eventos de pulsacion de teclas
function ini() {
var objs = getElementsById("input", "ip");
for (var i=0; i<objs.length; i++) {
if (window.event) {
objs[i].onkeydown = function() {filtroTeclado(event)};
objs[i].onkeyup = function() {entradaIP(event)};
} else {
objs[i].onkeydown = filtroTeclado;
objs[i].onkeyup = entradaIP;
}
}
}
Tambien son necesarias dos funciones: una para que nos devuelva los elementos del mismo tipo (tag) que tiene el mismo id, y otra que nos devuelve el siguiente elemento en orden de la lista obtenida anteriormente.
// Devuelve los elementos de cierto tipo (tag) que tienen el mismo id
function getElementsById(tag, id) {
var objs = document.getElementsByTagName(tag);
var res = new Array();
for (var i=0; i<objs.length; i++) {
if (objs[i].id == id) {
objs[i].rel = res.length;
res[res.length] = objs[i];
}
}
return res;
}
// Devuelve el siguiente objeto en el arrays de objetos con el mismo id
function dameSiguiente(obj) {
var objs = getElementsById("input", "ip");
var res = null;
for (var i=1; i<objs.length; i++) {
if (obj == objs[i-1]) {
res = objs[i];
}
}
return res;
}
Dentro de las funciones que se encargan de la gestión del control, son necesarias dos: una que evita la pulsación de teclas no deseadas
// Solo permito teclear letras, el punto y teclas de control
function filtroTeclado(evt) {
if (evt.keyCode != 190 && // .
evt.keyCode != 9 && // tab
evt.keyCode != 8 && // borrar <-
!((evt.keyCode >= 96 && evt.keyCode <=105) || evt.keyCode == 110) && // teclado numerico
!evt.ctrlKey && !evt.altKey && !evt.shiftKey && // CTRL, ALT, SHIFT
!String.fromCharCode(evt.keyCode).match(/\d/)) { // num
evt.returnValue = false;
return false;
}
}
y otra que se encarga de la gestión de las cajas: si se pulsa un punto que pase a la siguiente caja y si ocupa mas de tres digitos reparta el contenido en las otras cajas
// Gestiona el control de direcciones IP
function entradaIP(evt) {
// Obtengo el objeto que recibe el evento del teclado
var obj = null;
if (evt.srcElement) {
obj = evt.srcElement;
} else {
obj = evt.target;
}
var txt = obj.value;
// Si pulso el punto paso a la siguiente caja de texto
// El punto se permite pulsar pero no se debe mostrar
if (txt.substring(txt.length-1) == '.') { // Pulso el punto
obj.value = txt.substring(0, txt.length-1);
var sig = dameSiguiente(obj);
if (sig != null && txt != ".") sig.focus();
evt.returnValue = false;
return false;
// Si la longitud que tiene es mayor que 3 (por ejemplo
// debido a un copy/paste, se reparte el contenido por el
// resto de las cajas
} else if (txt.length > 3) {
var nums = new Array();
// Si tiene puntos se divide por los puntos
if (txt.indexOf(".") > -1) {
nums = txt.split(".");
// Si no tiene puntos, se divide en numeros de 3 digitos
} else {
for (var i=0; i<txt.length/3; i++) {
nums[nums.length] = txt.substring(i*3, i*3+3);
}
}
var act = obj;
var cont = 0;
// Se modifican los elementos posteriores
while (act != null && cont<nums.length) {
act.value = nums[cont++];
act = dameSiguiente(act);
}
}
}
Se le podrÃa añadir la funcionalidad de controlar si es una dirección IP válida, no permitiendo números mayores de 255 o el número 0, pero eso lo dejo para otro dÃa.