Foros del Web » Programando para Internet » Javascript »

Problema con DOM

Estas en el tema de Problema con DOM en el foro de Javascript en Foros del Web. Me presento me llamo Sebastián y estoy aprendiendo Javascript, ya hace un tiempo vengo programando con PHP pero en muchos casos requiero utilizar el famoso ...
  #1 (permalink)  
Antiguo 17/02/2006, 16:45
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
Problema con DOM

Me presento me llamo Sebastián y estoy aprendiendo Javascript, ya hace un tiempo vengo programando con PHP pero en muchos casos requiero utilizar el famoso lenguaje JS para poder realizar acciones sin tener que recargar la pagina, paso a contarles mi problema: En este momento estoy armando un formulacion web que tiene un INPUT del tipo TEXT que recibe valores numericos del tipo naturales (enteros y mayores que 0), mi idea es la siguiente; tomando el valor numerico ingresado se tiene que agregar al form X inputs mas, para lograr esto hice lo siguiente:

Código:
<script language="javascript">
	function cantidad (id)
	{
		if (document.forms[0].pjs.value != 0)
		{
			var tbody = document.getElementById(id).getElementsByTagName("TBODY")[0];
			temp = document.getElementById("raw");
			if (temp)
			{
				tbody.removeChild(temp);
			}
			for (a=1;a<=document.forms[0].pjs.value;a++)
			{
				var row = document.createElement("TR");
				row.id = "raw";
				var td1 = document.createElement("TD");
				td1.width = "70px";
				td1.appendChild(document.createTextNode("Personaje:"));
				var td2 = document.createElement("TD");
				td2.width = "15px";
				var img1 = document.createElement("IMG");
				img1.src="system/images/empty.gif";
				img1.width = "0";
				td2.appendChild(img1);
				var td3 = document.createElement("TD");
				var input1 = document.createElement("INPUT");
				input1.type = "text";
				input1.name = "pj" + a;
				td3.appendChild(input1);
				var td4 = document.createElement("TD");
				td4.width = "20px";
				var td5 = document.createElement("TD");
				td5.width = "20px";
				td5.appendChild(document.createTextNode("Nivel:"));
				var td6 = document.createElement("TD");
				td6.width = "15px";
				var img2 = document.createElement("IMG");												img2.src="system/images/empty.gif";
				img2.width = "0";
				td6.appendChild(img1);
				var td7 = document.createElement("TD");
				var input2 = document.createElement("INPUT");
				input2.type = "text";
				input2.name = "pj" + a;
				td7.appendChild(input2);
				row.appendChild(td1);
				row.appendChild(td2);
				row.appendChild(td3);
				row.appendChild(td3);
				row.appendChild(td4);
				row.appendChild(td5);
				row.appendChild(td6);
				row.appendChild(td7);
				tbody.appendChild(row);
			}
		}
	}
</script>
Y dentro del html tengo lo siguiente:

Código:
<table cellpadding="0" cellspacing="0" id="prueba">
	<tbody>
	</tbody>
</table>
El problema con este codigo es el siguiente, en el momento que vos varias el valor del input numero, no borra todos los inputs que habia agregado antes y los sigue agregando, para que se entienda mejor: si tengia 4 inputs y modifico el valor a 6, en vez de aparecer solo 6 aparecen 10 (4+6=10), esto no deberia pasar ya que intento borrar todo cuando pongo:
Código:
temp = document.getElementById("raw");
	if (temp)
	{
		tbody.removeChild(temp);
	}
La verdad es que ya no se me ocurre que hacer para arreglarlo y tengo que terminar el trabajo rapido, si alguien me puede dar una mano estaria muy agradecido.

Desde ya gracias

Saludos
  #2 (permalink)  
Antiguo 17/02/2006, 17:40
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
una idea sensilla es:

cuando vas creando los input, seguramente lo haces dentro de algun otro objeto(normalmente dentro de div, span, hasta incluso dentro de alguna celda de una tabla) identificado con algun id (normalmente se acostumbra a llamarlo CONTENEDOR, aunque puede ser cualquier nombre), entonces para borrarlos de una forma simple podrías hacer:

Cita:
document.getElementById('contenedor').innerHTML="" ;
donde como ya te dije antes, contenedor es o una capa, o un span, o una celda, etc.
y luego lo generas como lo hacias antes.


No es demaciado elegante pero simple.

espero te sea útil.

saludos
__________________
by Capitán Buscapina
.
  #3 (permalink)  
Antiguo 17/02/2006, 17:56
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
intente hacer lo que me dijiste, pero no logro mucho me tira error el Script, hice esto:

Código:
if (document.forms[0].pjs.value != 0)
{
	var tbody = document.getElementById(id).getElementsByTagName("TBODY")[0];
	temp = document.getElementById("raw");
	if (temp)
	{
		document.getElementById(id).innerHTML="" ;
	}
}
La verdad me estoy volviendo loco.

Saludos
  #4 (permalink)  
Antiguo 17/02/2006, 18:04
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
y el parámetro id que objeto es??

si no entiendo mal, vos creas todos los elmentos dinamicamente dentro de <TBody>.

si es así, asignale un id a tbody y luego hacele el innerHTML
__________________
by Capitán Buscapina
.
  #5 (permalink)  
Antiguo 17/02/2006, 18:07
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
ahi el id es "prueba" que representa el id de la tabla y no del tbody, vos decis que intente con el tbody?

Saludos
  #6 (permalink)  
Antiguo 17/02/2006, 18:15
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
innerHTML se utiliza para introducir contenido HTML dentro de objetos (que lo permnitan) borrando su contenido anterior, si haces innerHTML="", no el esta asignando nada y por lo tanto borra todo lo que está dentro de ese objeto.


si lo que creas está dentro del tbody y en deteminado momneto lo queres poner "en blanco" haciendo innerHTML lo lográs facilmente.
__________________
by Capitán Buscapina
.
  #7 (permalink)  
Antiguo 17/02/2006, 18:21
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
sigue tirando error, dice que es un error desconocido... :(
  #8 (permalink)  
Antiguo 17/02/2006, 18:45
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
innerHTML no funca dentro del TBODY, pero creo que ya te lo solucioné

Cita:
<script language="javascript">
var a;
function cantidad (id)
{
if (document.forms[0].pjs.value != 0)
{
var tbody = document.getElementById(id).getElementsByTagName(" TBODY")[0];
temp = document.getElementById("raw");
if (a>0)
{
for(w=1;w<a+1;w++){
tbody.removeChild(document.getElementById('raw'+w) );
}
}

for (a=1;a<=document.forms[0].pjs.value;a++)
{
var row = document.createElement("TR");
row.id = "raw"+a;
var td1 = document.createElement("TD");
td1.width = "70px";
td1.appendChild(document.createTextNode("Personaje :"));
var td2 = document.createElement("TD");
td2.width = "15px";
var img1 = document.createElement("IMG");
img1.src="system/images/empty.gif";
img1.width = "0";
td2.appendChild(img1);
var td3 = document.createElement("TD");
var input1 = document.createElement("INPUT");
input1.type = "text";
input1.name = "pj" + a;
td3.appendChild(input1);
var td4 = document.createElement("TD");
td4.width = "20px";
var td5 = document.createElement("TD");
td5.width = "20px";
td5.appendChild(document.createTextNode("Nivel:")) ;
var td6 = document.createElement("TD");
td6.width = "15px";
var img2 = document.createElement("IMG");img2.src="system/images/empty.gif";
img2.width = "0";
td6.appendChild(img1);
var td7 = document.createElement("TD");
var input2 = document.createElement("INPUT");
input2.type = "text";
input2.name = "pj" + a;
td7.appendChild(input2);
row.appendChild(td1);
row.appendChild(td2);
row.appendChild(td3);
row.appendChild(td3);
row.appendChild(td4);
row.appendChild(td5);
row.appendChild(td6);
row.appendChild(td7);
tbody.appendChild(row);
}
}
}
</script></head>
uno de los errores era que si tenias 20 inputs, las veite filas iban a tener el mismo id, con el cambio cada fila tiene su id "row1" para la primera y "row20" para la última.

No se si es lo más optimo, pero funciona (al menos para mi).

saludos y disculpa por equivocar el rumbo en algun momento
__________________
by Capitán Buscapina
.
  #9 (permalink)  
Antiguo 17/02/2006, 19:14
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
fijate en tu code, cuando hace if (a>0) hasta ese momento a no existe.

Saludos
  #10 (permalink)  
Antiguo 17/02/2006, 19:34
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
sip, pero si te fijas , antes de la funcion, está definido
__________________
by Capitán Buscapina
.
  #11 (permalink)  
Antiguo 17/02/2006, 20:32
 
Fecha de Ingreso: enero-2006
Ubicación: Buenos Aires, Argentina
Mensajes: 299
Antigüedad: 18 años, 3 meses
Puntos: 5
Buenas.

A existe, es una variable global y la función puede leerla sin problemas. Aunque es cierto que la primera vez que se ejecute va a tener valor "undefined". Lo que hace falta es inicializarla, por ejemplo asignandole 0. Esto además va a impedir que entre en el if (a>0) la primera vez.

El problema que tenía el script está en los for (en los dos). A menos que sea necesario, por experiencia propia, siempre evita errores difíciles de rastrear empezar por 0 y hacer la comparación como < (en vez de <= ). (Muchas veces vas a estar referenciando elementos que internamente se indexan a partir de 0, con lo cual si te acostumbrás a hacerlo así, te ahorrás pasos; además, no tenés que estar sumando/restando en la parte condicional del for, etc: es más prolijo, legible y hasta lógico).

Bueno, cambiando esos detalles, a mí me funciona en FF e IE (entre paréntesis, el código original más innerHTML = "" andaba al pelo en FF, pero IE tiraba error; esa solución era más simple y elegante, pero lamentablemente, no se puede ignorar al IE, que suele ser bastante turrito)

Acá te dejo la parte modificada

Suerte
Califa

Código:
var a = 0;
function cantidad (id)
{
	//alert(a);
	if (document.forms[0].pjs.value != 0)
	{
		var tbody = document.getElementById(id).getElementsByTagName("TBODY")[0];
		temp = document.getElementById("raw");
		if (a>0)
		{
			for(w=0;w<a;w++)
			{
				tbody.removeChild(document.getElementById('raw'+w) );
			}
		}
		for (a=0;a<document.forms[0].pjs.value;a++)
		{
  #12 (permalink)  
Antiguo 17/02/2006, 22:35
Avatar de Cap.Buscapina  
Fecha de Ingreso: octubre-2004
Ubicación: Argentina
Mensajes: 836
Antigüedad: 19 años, 6 meses
Puntos: 4
hola califa010


vayamos por partes:

con respecto a la variable, al estar declarada al principio ya puede ser utilizada, es cierto que el valor de la variable la primera vez arrojará undefined, pero para este caso solo sirve para saber si es la primera vez que corre el script o no, luego la toma el for y la modifica a piachere.

y por último, aunque seguimos con la variable "a", puede comenzar por cualquier número,(0,1, 1000000 inclusive) ya que para eso se utiliza, lo mas común es comenzar de 0, pero depende de la utilización que se le de.(para no complicar aún mas la cosa , solo me limité a tratar de hacer funcionar el script sin necesidad de modificar demaciadas cosas).

el script original tenía dos problemas:
1.- Se le asignaba un mismo ID a las filas que se jeneraban dinamicamente (nunca iba a ser posible eliminarlas de esa manera.

2.- Solo eliminaba una fila, ya que no estaba dentro de ningun bucle.(por lo que el problema no era del DOM)



De todas formas siempre es bueno intercambiar opiniones, y lo que queda mas que claro que hay varios caminos para lograr un mismo resultado.

Saludos y arrivederchi.
__________________
by Capitán Buscapina
.
  #13 (permalink)  
Antiguo 18/02/2006, 01:11
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
gracias a todos ahora el code anda 10 puntos los felicito :D

Saludos
  #14 (permalink)  
Antiguo 18/02/2006, 01:44
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
solo me quedo una pequeña inquietud, resulta que el code anda bien pero en FF no me toma los espacios que le hago dejar con el width en esta parte:
Código:
var td2 = document.createElement("TD");
td2.width = "15px";
Esta propiedad no la lee bien el FF? porque me queda todo junto como si no existice el espacio.

Saludos y gracias por leer
  #15 (permalink)  
Antiguo 18/02/2006, 04:12
Avatar de tunait
Moderadora
 
Fecha de Ingreso: agosto-2001
Ubicación: Terok Nor
Mensajes: 16.805
Antigüedad: 22 años, 8 meses
Puntos: 381
Hola

El atributo width de las celdas cuando se dá como absoluto no requiere de especificar la medida (px).

Omite la medida o establecela desde su atributo style

td2.style.width = "15px";

Un saludo
  #16 (permalink)  
Antiguo 18/02/2006, 07:09
 
Fecha de Ingreso: febrero-2006
Mensajes: 21
Antigüedad: 18 años, 2 meses
Puntos: 0
Probe antes pasarlo como vos dijiste pero tampoco lo respecta el FF, les muestro el code como esta hoy:

Código:
<script language="javascript">
	var a = 0;
	function cantidad (id)
	{
		if (document.forms[0].pjs.value != 0)
		{
			var tbody = document.getElementById(id).getElementsByTagName("TBODY")[0];
			if (a>0)
			{
				for(w=0;w<a;w++)
				{
				tbody.removeChild(document.getElementById('raw'+w) );
				tbody.removeChild(document.getElementById('raw2'+w) );
				}
			}
			for (a=0;a<document.forms[0].pjs.value;a++)
			{
				var row = document.createElement("TR");
				row.id = "raw" + a;
				var td1 = document.createElement("TD");
				td1.style.width = "700px";
				td1.appendChild(document.createTextNode("Personaje:"));
				var td2 = document.createElement("TD");
				td2.style.width = "15px";
				var img1 = document.createElement("IMG");
				img1.src="system/images/empty.gif";
				img1.width = "0";
				td2.appendChild(img1);
				var td3 = document.createElement("TD");
				var input1 = document.createElement("INPUT");
				input1.type = "text";
				input1.name = "pj" + a;
				td3.appendChild(input1);
				var td4 = document.createElement("TD");
				td4.style.width = "20px";
				var td5 = document.createElement("TD");
				td5.style.width = "20px";
				td5.appendChild(document.createTextNode("Nivel:"));
				var td6 = document.createElement("TD");
				td6.style.width = "15px";
				var img2 = document.createElement("IMG");
				img2.src="system/images/empty.gif";
				img2.width = "0";
				td6.appendChild(img1);
				var td7 = document.createElement("TD");
				var input2 = document.createElement("INPUT");
				input2.type = "text";
				input2.name = "pj" + a;
				td7.appendChild(input2);
				var row2 = document.createElement("TR");
				row2.id = "raw2" + a;
				var td8 = document.createElement("TD");
				td8.height = "5px";
				td8.colspan = "7"; 
				row.appendChild(td1);
				row.appendChild(td2);
				row.appendChild(td3);
				row.appendChild(td3);
				row.appendChild(td4);
				row.appendChild(td5);
				row.appendChild(td6);
				row.appendChild(td7);
				row2.appendChild(td8);
				tbody.appendChild(row);
				tbody.appendChild(row2);
			}
		}
	}
</script>
Saludos
  #17 (permalink)  
Antiguo 18/02/2006, 11:23
 
Fecha de Ingreso: enero-2006
Ubicación: Buenos Aires, Argentina
Mensajes: 299
Antigüedad: 18 años, 3 meses
Puntos: 5
Capitán, coincido con Vd...

Es cierto que un for puede empezar en cualquier valor e ir "para adelante" o "para atrás", según se necesite. Pero si el valor del contador no es significativo y no lo usamos para ninguna otra cosa que para mantener una referencia interna, termina por ser más simple y práctico empezar de 0, para mí. Fue lo que hice ayer cuando vi el script, para ver si le podía encontrar una solución rápida al problema.

Ahora, revisando de vuelta la otra versión (con a=1 y w=1), encontré el error. Estaba en el primer for:

Código:
for (w=1;w<a+1;w++)
que estaba haciendo una vuelta de más por la condición w<a+1. Si querés chequealo con estos alerts y vas a ver lo que te digo mejor que si trato de explicártelo con palabras.

Código:
var a = 0;
function cantidad (id)
{
	alert("a al inicio="+a);
	if (document.forms[0].pjs.value != 0)
	{
		var tbody = document.getElementById(id).getElementsByTagName("TBODY")[0];
		temp = document.getElementById("raw");
		if (a>0)
		{
			for(w=1;w<a;w++) // antes (w=1;w<a+1;w++)
			{
				alert("w en remove child="+w);
				tbody.removeChild(document.getElementById('raw'+w) );
			}
		}
		for (a=1;a<=document.forms[0].pjs.value;a++)
		{
Bueno, cuestión que, como te decía, me parece más fácil arrancar siempre de 0 y usar < en la condición si no es indispensable hacerlo de otra manera, porque te evita estos errores que no son tan fáciles de detectar (yo no lo vi de una, tuve que empezar a poner alerts y demás).

Suerte
Califa
  #18 (permalink)  
Antiguo 21/02/2006, 07:39
 
Fecha de Ingreso: febrero-2006
Mensajes: 31
Antigüedad: 18 años, 2 meses
Puntos: 1
Necesito ayuda con el width, porque he puesto las formas que tienen arriba pero no funciona , es como si no pusiera nada
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:01.