Foros del Web » Programando para Internet » Javascript »

Se me superponen los eventos y el script no hace nada

Estas en el tema de Se me superponen los eventos y el script no hace nada en el foro de Javascript en Foros del Web. Hola chic@s me he aquí con un problemita con los eventos. Voy a tratar de explicarme lo mejor posible: tengo un campo input en el ...
  #1 (permalink)  
Antiguo 21/02/2006, 18:16
 
Fecha de Ingreso: agosto-2005
Ubicación: Argentina, Capital Federal
Mensajes: 435
Antigüedad: 18 años, 8 meses
Puntos: 2
Se me superponen los eventos y el script no hace nada

Hola chic@s me he aquí con un problemita con los eventos.

Voy a tratar de explicarme lo mejor posible: tengo un campo input en el cual al escribir mas de dos letras se llena debajo un div con palabras q comiencen con esas letras escritas (tipo suggest de Gmail). En ese div se puede "navegar" entre las palabras arrojadas y seleccionar una haciendole clic y que esa palabra se ponga en el campo input que mencioné antes. Hasta ahí todo perfecto, el problema viene cuando intento ocultar ese div una vez que se selecciona una palabra o cuando se hace clic fuera del div.

Se me ocurrió poner en el input un evento onBlur que oculte el div cuando se quita el foco de ese input, el problema es que cada elemento de la lista que compone ese div (las palabras sugeridas) tienen en si mismas un evento onClick para que cuando las cliqueen se llene el input con la palabra que corresponda. Entonces al cliquearlas el div efectivamente se oculta, pero nunca se me rellena el input.

A continuación pongo pedazos de código para intentar darme a entender mejor:

Código:
<table border="1" width="400" style="border-style:none;">
<tr>
<td id="fila_2" width="50%" class="punteado">
	<div id="contenedor">
	<input onBlur="document.getElementById('lista').style.display='none'" onKeyUp="rellenaCampo()" type="text" id="input_2" class="ingreso" />
	<div id="lista"></div>
	</div>
</td>
</tr>
</table>
En ese código tengo declarado el input y el div. Por medio de ajax al escribir mas de 2 letras hago aparecer en ese div el listado de palabras del cual hablé con el siguiente evento (cada una de las palabras lo contiene):

Código:
onClick="document.getElementById('input_2').value='xxxxxx'"
El tema, como mencione antes, es que al hacer clic el div si se oculta, pero el input no se llena con nada. Si le saco el onBlur al input se llena perfectamente, pero la lista queda eternamente en pantalla, con lo que llego a la conclusión de que los eventos se me superponen (?).

Estaré sumamente agradecido a su ayuda, y no duden en avisarme si no se entiende nada lo que expliqué.

Se les agradece de antemano. Saludos.
__________________
R4DS en español | R4DS en inglés
  #2 (permalink)  
Antiguo 21/02/2006, 18:31
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
y por que no aprovechar ese mismo evento (onclick):

Cita:
onClick="document.getElementById('input_2').value= 'xxxxxx';document.getElementById('lista').style.di splay='none';"
espero que sea lo que necesitas.

saludos
__________________
by Capitán Buscapina
.
  #3 (permalink)  
Antiguo 21/02/2006, 18:40
 
Fecha de Ingreso: agosto-2005
Ubicación: Argentina, Capital Federal
Mensajes: 435
Antigüedad: 18 años, 8 meses
Puntos: 2
Antes que nada agradezco enormemente tu pronta respuesta.

Te comento que probé colocar el display='none' en el onClick de cada palabra, y funciona bárbaro si esta solo, pero en conjutno con el onBlur del input sigue sin hacer nada.
El tema es que si le quito el onBlur al input, si el usuario no selecciona nada de la lista, esta quedaría eternamente en pantalla.

Sinceramente estoy perdido.

Nuevamente te agradezco la respuesta.
Saludos.
__________________
R4DS en español | R4DS en inglés
  #4 (permalink)  
Antiguo 21/02/2006, 20:41
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
lo que ocurre que mientras tengas el onblur en el imput y hagas click fuera de el, se dispara antes el onblur.

Mal y pronto se me ocurren dos soluciones.

1- colocarle de alguna forma un setTimeOut para que luego de algunos segundos desaparesca la capa (de las dos la peor opcion)

2.- colocarle el evento onfocus al objeto siguiente( otro input, boton, etc) para que cuando ingrese se oculte la capa.

Espero que no te enrriede aún mas.

saludos

PD: ayudaría si pones algo de codigo, un ejemplito (simplificado) con dos o tres opciones.
__________________
by Capitán Buscapina
.
  #5 (permalink)  
Antiguo 22/02/2006, 10:23
 
Fecha de Ingreso: agosto-2005
Ubicación: Argentina, Capital Federal
Mensajes: 435
Antigüedad: 18 años, 8 meses
Puntos: 2
Hola, gracias nuevamente.

Lo del setTimeOut no es mala idea, pero de hecho preferiría que sea el "plan B", tu 2º idea de la del foco no acabo de comprenderla.

A continuación pego un ejemplito con mi problema simplificado al máximo:

Código:
<html>
<head>
<style type="text/css"> 
#lista
{
	background-color:#EAEAEA;
	position:absolute;
	width:120px;
	top:100px;
	left:100px;
	display:none;
} 

.resaltado
{
	background-color:#FFFFFF; 
	cursor:pointer;
}

.normal
{
	background-color:#EAEAEA;
}
</style>

<script language="javascript" type="text/javascript">
function rellenaCampo()
{	
	campo=document.getElementById("input_2");
	div=document.getElementById("lista");
	valor=campo.value;
	
	if(valor.length>=2) div.style.display="block";
}

</script>
</head>
<body>
<input onBlur="document.getElementById('lista').style.display='none'" onKeyUp="rellenaCampo()" type="text" id="input_2" />

<div id="lista">

<div id="1" onClick="document.getElementById('input_2').value=this.innerHTML; document.getElementById('lista').style.display='none'" onMouseOut="this.className='normal'" onMouseOver="this.className='resaltado'">Elemento 1</div>

<div id="2" onClick="document.getElementById('input_2').value=this.innerHTML; document.getElementById('lista').style.display='none'" onMouseOut="this.className='normal'" onMouseOver="this.className='resaltado'">Elemento 2</div>

</div>
</body>
</html>
Ahí se ve claramente lo que tu dices, primero se ejecuta el onBlur y luego el onClick, y si le saco el onBlur la lista quedaría eternamente en pantalla hasta que se cliquee una opción, y si le saco el onClick no puedo rellenar en input con la opción elegida.

Espero no abusar de su paciencia.
Un saludo.
__________________
R4DS en español | R4DS en inglés

Última edición por zaqpz; 22/02/2006 a las 11:00
  #6 (permalink)  
Antiguo 22/02/2006, 17:10
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
quedaría algo así:
Cita:
<html>
<head>
<style type="text/css">
#lista
{
background-color:#EAEAEA;
position:absolute;
width:120px;
top:100px;
left:100px;
display:none;
}

.resaltado
{
background-color:#FFFFFF;
cursor:pointer;
}

.normal
{
background-color:#EAEAEA;
}
</style>

<script language="javascript" type="text/javascript">
var v=0;
function rellenaCampo()
{
campo=document.getElementById("input_2");
div=document.getElementById("lista");
valor=campo.value;

if(valor.length>=2) div.style.display="block";v=1;
}

</script>
</head>
<body>
<input onBlur="document.getElementById('lista').style.dis play=(v==0)?'none':'block'" onKeyUp="rellenaCampo()" type="text" id="input_2" />

<div id="lista">

<div id="1" onClick="v=0;document.getElementById('input_2').value=this.inne rHTML; document.getElementById('lista').style.display='no ne'" onMouseOut="this.className='normal'" onMouseOver="this.className='resaltado'">Elemento 1</div>

<div id="2" onClick="v=0;document.getElementById('input_2').value=this.inne rHTML; document.getElementById('lista').style.display='no ne'" onMouseOut="this.className='normal'" onMouseOver="this.className='resaltado'">Elemento 2</div>

</div>

</body>
</html>

lo que está en rojo son las modificaciones(si no me alvidé de nada ).

Adicionalmente, y solo como sugerencia, deberías contemplar la posibilidad de que se pueda utilizar también el teclado para seleccionar de la lista.(por ejemplo: cuando se depliega la lista , que al precionar la flechita para abajo se pueda seleccionar la que uno quiere, y con el enter o espacio confirmar).

Es solo una idea, saludos
__________________
by Capitán Buscapina
.
  #7 (permalink)  
Antiguo 23/02/2006, 08:33
 
Fecha de Ingreso: agosto-2005
Ubicación: Argentina, Capital Federal
Mensajes: 435
Antigüedad: 18 años, 8 meses
Puntos: 2
De acuerdo

Agradezco x 3º vez tu respuesta y tu tiempo dedicado.
Te comento que no lo pude hacer funcionar, seguramente estoy haciendo algo mal.
Cuando cliqueo en alguna opción se cierra lo mas bien. Pero cuando cliqueo en alguna otra parte queda abierto. No soy capaz de encontrarle la vuelta.
Si logro dar con la solución la posteo aquí mismo.

Un saludo.
__________________
R4DS en español | R4DS en inglés
  #8 (permalink)  
Antiguo 23/02/2006, 09:49
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
ok, probalo ahora:
Cita:
<html>
<head>
<script language="javascript" type="text/javascript">
var v=1;
function rellenaCampo()
{
campo=document.getElementById("input_2");
div=document.getElementById("lista");
valor=campo.value;

if(valor.length>=2) div.style.display="block";
}

</script>
</head>
<body >
<input onBlur="if(v==1){document.getElementById('lista'). style.display='none';}" onKeyUp="rellenaCampo()" type="text" id="input_2" />
<div id="lista" >

<div id="1" onClick="v=0;document.getElementById('input_2').va lue=this.innerHTML; document.getElementById('lista').style.display='no ne'" onMouseOut="this.className='normal';v=1;" onMouseOver="this.className='resaltado';v=0;">Elemento 1</div>

<div id="2" onClick="v=0;document.getElementById('input_2').va lue=this.innerHTML; document.getElementById('lista').style.display='no ne'" onMouseOut="this.className='normal';v=1;" onMouseOver="this.className='resaltado';v=0;">Elemento 2</div>
</div>
</body>
</html>
algo que simplificaría bastante es que en lugar de utilizar div's para simular una lista, utilices un select (lista), con eso te ahorrás el tema no poder utilizar el teclado. Claro que esto es solo una sugerencia.

Espero que esta sea la solución.
saludos

pd:cuidado con los espacios en blanco que agrega el foro .
__________________
by Capitán Buscapina
.
  #9 (permalink)  
Antiguo 23/02/2006, 10:23
 
Fecha de Ingreso: agosto-2005
Ubicación: Argentina, Capital Federal
Mensajes: 435
Antigüedad: 18 años, 8 meses
Puntos: 2
Perfecto, un 4º sincero agradecimiento por tu tiempo.
Me permití hacerle un pequeño cambio al valor de "v" en el onClick para que en Firefox también cerrara la lista. Y pase todo a funciones a razón de postearlo y que quizá le sirva a alguien mas:

Código:
<html>
<head>
<style type="text/css"> 
#lista
{
background-color:#EAEAEA;
position:absolute;
width:120px;
top:100px;
left:100px;
display:none;
} 

.resaltado
{
background-color:#FFFFFF; 
cursor:pointer;
}

.normal
{
background-color:#EAEAEA;
}
</style>

<script language="javascript" type="text/javascript">
var v=1;

function rellenaCampo()
{
	campo=document.getElementById("input_2");
	div=document.getElementById("lista");
	valor=campo.value;

	if(valor.length>=2) div.style.display="block";
}

function clickLista(elemento)
{
	v=1;
	document.getElementById('input_2').value=elemento.innerHTML;
	document.getElementById('lista').style.display='none';
	elemento.className='normal';
}

function mouseFuera(elemento)
{
	v=1;
	elemento.className='normal'; 
}

function mouseDentro(elemento)
{
	v=0;
	elemento.className='resaltado'; 
}
</script>
</head>

<body>
<input onBlur="if(v==1) { document.getElementById('lista').style.display='none'; }" onKeyUp="rellenaCampo()" type="text" id="input_2" />

<div id="lista">
<div id="1" onClick="clickLista(this);" onMouseOut="mouseFuera(this);" onMouseOver="mouseDentro(this);">Elemento 1</div>

<div id="2" onClick="clickLista(this);" onMouseOut="mouseFuera(this);" onMouseOver="mouseDentro(this);">Elemento 2</div>
</div>

</body>
</html>
Bueno al fin puedo continuar con el desarrollo del suggest con AJAX. Cuando esté terminado lo subiré para compartir su fuente con los créditos al Sr. (xD) Cap.Buscapina que correspondan.

Cita:
Iniciado por Cap.Buscapina
algo que simplificaría bastante es que en lugar de utilizar div's para simular una lista, utilices un select (lista), con eso te ahorrás el tema no poder utilizar el teclado. Claro que esto es solo una sugerencia.
Estoy viendo el tema del uso del teclado. Pensaba capturar el uso de algunas teclas mientras el div este en pantalla para darle funcionalidad. Pero creo que lo haré en un futuro, aunque no tan lejano. Quizá lo haga en un select, ya veré.

Bueno en fin, se agradece nuevamente y cuando tenga el ejemplito terminado volveré a dejarles los zip para descargar.

Un saludo!
__________________
R4DS en español | R4DS en inglés
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:38.