AutoSuggest con Javascript

0 - - 27/06/2007 19:40:48

El siguiente script permite la creación de un sistema de sugerencias o "autosuggest" únicamente mediante javascript, sin ningún tipo de dependencias de librerías como jQuery o Mootools. Este código me ha sido útil en más de una ocasión, para realizar un sistema de sugerencias del lado del cliente. El código es una adaptación de uno que encontré navegando por internet -no recuerdo la url- y en este ejemplo se muestra sin CSS para no añadir más líneas de código a este post.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>AutoSuggest</title>
</head>
<body>
<form>
  <input type="text" id="caja_mapa" name="caja_mapa" size="20" maxlength="100" />
 </form>
      <div id="sugerencias"><ul></ul></div>
<script type="text/javascript">
    function AutoSuggest(elem, elementos_posibles){
    var me = this;
    this.elem = elem;
    this.elementos_posibles = elementos_posibles;
    this.elegible = new Array();
    this.textoEntrada = null;
    this.highlighted = -1;
    this.div = document.getElementById("sugerencias");
    var TAB = 9;
    var ESC = 27;
    var KEYUP = 38;
    var KEYDN = 40;
    elem.setAttribute("autocomplete","off");
    
    if(!elem.id){
    	var id = "sugerencias" + idContador;
    	idContador++;
    	elem.id = id;
    }
      
      
    elem.onkeydown = function(ev) {
    	var key = me.getKeyCode(ev);
    	switch(key) {
    		case TAB:
    		me.usarSugerencia();
    		break;
    
    		case ESC:
    		me.ocultarDiv();
    		break;
    
    		case KEYUP:
    		if (me.highlighted > 0){
    			me.highlighted--;
    		}
    		me.cambiarResaltado(key);
    		break;
    
    		case KEYDN:
    		if (me.highlighted < (me.elegible.length - 1)){
    			me.highlighted++;
    		}
    		me.cambiarResaltado(key);
    		break;
    	}
    };
      
    elem.onkeyup = function(ev) {
    	var key = me.getKeyCode(ev);
    	switch(key){
    	case TAB:
    	case ESC:
    	case KEYUP:
    	case KEYDN:
    	return;
    	default:
    
    		if (this.value != me.textoEntrada && this.value.length > 0){
    			me.textoEntrada = this.value;
    			me.getEligible();
    			me.crearDiv();
    			me.posicionarDiv();
    			me.mostrarDiv();
    		}else{
    			me.ocultarDiv();
    		}
    	}
    };
    
    this.usarSugerencia = function(){
    	if (this.highlighted > -1){
    		this.elem.value = this.elegible[this.highlighted];
    		this.ocultarDiv();
    		setTimeout("document.getElementById('" + this.elem.id + "').focus()",0);
    	}
    };
    
    this.mostrarDiv = function(){
    	this.div.style.display = 'block';
    };
    
    this.ocultarDiv = function(){
    	this.div.style.display = 'none';
    	this.highlighted = -1;
    };
    
    this.cambiarResaltado = function() {
    	var lis = this.div.getElementsByTagName('LI');
    	for (i in lis){
    		var li = lis[i];
    		if (this.highlighted == i){
    			li.className = "selected";
    		}else{
    			li.className = "";
    		}
    	}
    };
    
    this.posicionarDiv = function(){
    	var el = this.elem;
    	var x = 0;
    	var y = el.offsetHeight;
    
    	while (el.offsetParent && el.tagName.toUpperCase() != 'BODY'){
    		x += el.offsetLeft;
    		y += el.offsetTop;
    		el = el.offsetParent;
    	}
    	x += el.offsetLeft;
    	y += el.offsetTop;
    	this.div.style.left = x + 'px';
    	this.div.style.top = y + 'px';
    };

	this.crearDiv = function(){
		var ul = document.createElement('ul');
        for (i=0;i<this.elegible.length;i++){
    			var word = this.elegible[i];
    			var li = document.createElement('li');
    			var a = document.createElement('a');
    			a.href="javascript:false";
    			a.innerHTML = word;
    			li.appendChild(a);
    	
    			if (me.highlighted == i) {
    				li.className = "selected";
    			}
    			ul.appendChild(li);
    		}
	
		this.div.replaceChild(ul,this.div.childNodes[0]);
	
		ul.onmouseover = function(ev){
			var target = me.getEventSource(ev);
			while (target.parentNode && target.tagName.toUpperCase() != 'LI'){
				target = target.parentNode;
			}
			var lis = me.div.getElementsByTagName('LI');
	
			for (i in lis){
				var li = lis[i];
				if(li == target){
					me.highlighted = i;
					break;
				}
			}
			me.cambiarResaltado();
		};
		ul.onclick = function(ev){
			me.usarSugerencia();
			me.ocultarDiv();
			me.cancelarEvento(ev);
			return false;
		};
		this.div.className="suggestion_list";
		this.div.style.position = 'absolute';
	};
    
	this.getEligible = function(){
		this.elegible = new Array();
        for (i=0;i<this.elementos_posibles.length;i++){
    			var sugerido = this.elementos_posibles[i];
    			if(sugerido.toLowerCase().indexOf(this.textoEntrada.toLowerCase()) != "-1"){
    				this.elegible[this.elegible.length]=sugerido;
    			}
		}
	};
	this.getKeyCode = function(ev){
		if(ev){
			return ev.keyCode;
		}
		if(window.event){
			return window.event.keyCode;
		}
	};

	this.getEventSource = function(ev){
		if(ev){
			return ev.target;
		}
		if(window.event){
			return window.event.srcElement;
		}
	};

	this.cancelarEvento = function(ev){
		if(ev){
			ev.preventDefault();
			ev.stopPropagation();
		}
		if(window.event){
			window.event.returnValue = false;
		}
	}
}
var palabras = new Array('algo','casa','campo','altavoz','coche','alfombra','libro','papel','pantalla','mesa','archivos');
new AutoSuggest(document.getElementById('caja_mapa'),palabras);
</script>
</body>
</html>

Ver ejemplo en funcionamiento » »

Deja tu comentario

  • El comentario debe estar relacionado con el contenido de la entrada.
  • Comentarios ofensivos, con spam o con lenguaje inapropiado serán eliminados.

captcha