Foros del Web » Programando para Internet » Javascript »

Poner <input type="text" en diferentes partes al pulsar un botón

Estas en el tema de Poner <input type="text" en diferentes partes al pulsar un botón en el foro de Javascript en Foros del Web. A ver si podeis ayudarme... Lo qe quiero conseguir (y no se si se puede) hacer una jerarquía de <input type="text"... al pulsar un botón ...
  #1 (permalink)  
Antiguo 24/08/2008, 09:01
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Poner <input type="text" en diferentes partes al pulsar un botón

A ver si podeis ayudarme...
Lo qe quiero conseguir (y no se si se puede) hacer una jerarquía de <input type="text"... al pulsar un botón aparece el primero, si pulso ese input y vuelvo a pulsar el botón debería aparecer otro <input... debajo del anterior pero un poco a la derecha, si no tengo pulsado ningún <input... al darle al boton aparecería el <input... al final, a la izquierda (como el primero).

Ahora mismo, como no sé si se pueden seleccionar <input y hacer lo que quiero, lo único que intento es que al pulsar un botón aparezcan <inputs a la izquierda y al pulsar otro aparezcan los inputs un poco a la derecha... pero no lo consigo, aparecen siempre unos debajo de otros... Os dejo el código... a ver si veis que es lo que falla...

Código:
<script>

num=0;
function crear(obj) {
  num++;
  fi = document.getElementById('fiel'); // 1
  contenedor = document.createElement('div'); // 2
  contenedor.id = 'div'+num; // 3
  contenedor.style.float='left';
  contenedor.style.width = '45%';
  
  fi.appendChild(contenedor); // 4

  ele = document.createElement('input'); // 5
  ele.type = 'text'; // 6
  ele.name = 'cap'+num; // 6
  contenedor.appendChild(ele); // 7
  
  ele = document.createElement('input'); // 5
  ele.type = 'button'; // 6
  ele.value = 'Borrar'; // 8
  ele.name = 'div'+num; // 8
  ele.onclick = function () {borrar(this.name)} // 9
  contenedor.appendChild(ele); // 7
}
function borrar(obj) {
  fi = document.getElementById('fiel'); // 1 
  fi.removeChild(document.getElementById(obj)); // 10
}

num1=0;
function crear1(obj) {
  num1++;
  fi = document.getElementById('fiel1'); // 1
  contenedor = document.createElement('div'); // 2
  contenedor.id = 'sub'+num1; // 3
  contenedor.style.float='left';
  contenedor.style.width = '45%';
  fi.appendChild(contenedor); // 4

  ele = document.createElement('input'); // 5
  ele.type = 'text'; // 6
  ele.name = 'scap'+num1; // 6
  contenedor.appendChild(ele); // 7
  
  ele = document.createElement('input'); // 5
  ele.type = 'button'; // 6
  ele.value = 'Borrar'; // 8
  ele.name = 'sub'+num1; // 8
  ele.onclick = function () {borrar1(this.name)} // 9
  contenedor.appendChild(ele); // 7
}
function borrar1(obj) {
  fi = document.getElementById('fiel1'); // 1 
  fi.removeChild(document.getElementById(obj)); // 10
}

</script>
Código HTML:
<div>
  <div align="center">
  	<input type="button" value="capitulo" name="capitulo" onclick="crear(this)"/>
  	<input type="button" value="subcapitulo" name="subcapitulo" onclick="crear1(this)"/>
  </div>
</div> 
Muchas gracias
  #2 (permalink)  
Antiguo 24/08/2008, 09:12
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola scorm:

Al parecer las dos funciones hacen lo mismo. ¿Quieres decir que quieres identar la caja de texto que se ha creado con crear1()? Eso lo conseguiríamos con estilos CSS fácilmente. Prueba a darle un poco de margin-left a tu capa contenedor cuando la crees:

Código PHP:
contenedor.style.marginLeft "2em"
¿Era eso lo que querías conseguir?
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #3 (permalink)  
Antiguo 24/08/2008, 09:38
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

ESO ERA!!!! q fácil cuando ya lo sabes jejeje. Muchas gracias

Ahora te quería hacer la otra pregunta, sabes si es posible lo que quiero hacer de pulsar un <input... y dejarlo seleccionado, para que al pulsar el botón aparezca el nuevo <input identado respecto al seleccionado?

Muchas gracias
  #4 (permalink)  
Antiguo 24/08/2008, 10:20
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola de nuevo:

No, no puedes "dejarlo seleccionado", pero podemos hacer un apaño javascript para que parezca que está seleccionado. Jugamos con estilos y al cliente le parecerá intuitivamente que uno está activo y los demás inactivos.

Eso sí, habrá que crearlos todos en una misma capa. Al crearlo comprobaríamos cuál está activo y lo añadiríamos debajo (busca un insertAfter(), que no existe por defecto).

Es más complicado de lo que parece al final, pero con unos cuantos intentos igual lo consigues.


Saludos.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #5 (permalink)  
Antiguo 24/08/2008, 14:14
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Y existe una forma más fácil???
La idea es esa, que pueda poner una jerarquía de inputs como el usuario quiera...Se os ocurre algo? es que poner un botón al lado de cada input, por si quiere el usuario que tenga o no un 'sub input'...es un poco cutre no? Es que no se me ocurre nada mejor...
  #6 (permalink)  
Antiguo 24/08/2008, 16:24
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola de nuevo:

No, no veo nada más sencillo. De momento he simplificado algunos aspectos. Con cloneNode() podemos ahorrarnos bastantes líneas. Y no he encontrado otra manera de hacerlo que colocando un botón a cada pareja para dibujar un hijo. Dándole estilos no creo que quede cutre.

Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<
head>
<
meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<
meta name="Author" content="derkeNuke" />
<
title>Página nueva</title>
<
style type="text/css">
/*div { border: solid 1px red; }*/
</style>
</
head>

<
body>


<
div>
  <
div align="center">
      <
input type="button" value="capitulo" name="capitulo" onclick="crear(this)"/>
  </
div>
</
div>

<
div id="modulo" style="display:none">
    <
input type="text" name="cap" />
    <
button type="button" name="div" onclick="borrar(this.parentNode)">borrar</button>
    <
button type="button" name="hijo" onclick="crear(this)">hijo</button>
</
div>

<
div id="fiel"></div>

<
script type="text/javascript">
<!--


function 
insertAfter(nodereferenceNode) {
    
referenceNode.parentNode.insertBefore(nodereferenceNode.nextSibling);
}  


var 
num=0;
function 
crear(obj) {
    
num++;
    var 
fi document.getElementById('fiel'); // 1
    
var copia document.getElementById("modulo").cloneNode(true);
    
copia.style.display "block";
    
    
// obj es el botón
    // obj.parentNode es el div que contiene al text+boton

    
if( obj.value==="hijo" ) {
        var 
anteriorMargin parseInt(obj.parentNode.style.marginLeft) || 0;
        
copia.style.marginLeft = (anteriorMargin+2) +"em";
        
insertAfter(copiaobj.parentNode);
        
// al pulsar boton 'borrar' del padre que se borren también los hijos
        
var botonBorrar obj.parentNode.getElementsByTagName("button")[0];
        var 
anteriorBorrar botonBorrar.onclick;
        
botonBorrar.onclick = function() {
            
anteriorBorrar.callthis );
            
borrar(copia);
        }
    }
    else {
        
fi.appendChild(copia); // 7
    
}    
}
function 
borrar(obj) {
    
fi document.getElementById('fiel'); // 1 
    
fi.removeChild(obj); // 10
}




// -->
</script>

</body>
</html> 
Quedan aspectos por limar. No he tocado nada de atributos id y name, eso es relativamente fácil. Cuando se borra un padre, se borran todos los hijos, pero eso no pasa si se borra un abuelo (si existe un hijo de hijo de hijo y se le da a 'borrar' en el abuelo el nieto queda sin borrarse).

Creo que es tan complicado y te vas a comer tanto la cabeza que es mejor cambiar el sistema completo y quizás hacerlo con listas, que es lo que semánticamente estamos escribiendo. Con una lista sabríamos qué cuelga de qué con DOM. Con DIVs es más complicado ya que sólo sabemos si cuelga por el estilo CSS que denota el margin.


Yo lo intentaría con listas.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #7 (permalink)  
Antiguo 24/08/2008, 18:36
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Mira te enseño lo que llevo hasta ahora, mi principal problema hasta ahora (y gracias a tu código he llegado hasta aquí) es que si creo hijos e hijos de hijos (en una primera tanda) se crean bien, pero al intentar crear un nuevo hijo del primer padre, no me lo muestra el último, como debería ser... te enseño el código. Ahora funciona de la siguiente manera, cada vez que le doy a 'capitulo' si el foco está en un input le crea un hijo, si no está posicinado en ningún input no hace nada.

Código:
function insertAfter(node, referenceNode) {
    referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
}  

var foco=0;
function seleccionados(){
	if(foco!=0){
       	var fi = document.getElementById('fiel'); // 1
    	var copia = document.getElementById("modulo").cloneNode(true);
    	copia.style.display = "block";

        var anteriorMargin = parseInt(foco.parentNode.style.marginLeft) || 0;
		copia.style.marginLeft = (anteriorMargin+2) +"em";
		insertAfter(copia, foco.parentNode);
		
		 //fi.appendChild(copia);
    	
	}
	foco=0;
}

<div>
  <div align="center">
  	<input type="button" value="capitulo" name="capitulo" onclick="seleccionados()"/>
  </div>
</div>


<div>
  <div id="fiel" align='left' >
	<input type="text" name="cap3" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'"/>  	  	
  </div>
</div>  

<div id="modulo" style="display:none">
    <input type="text" name="cap" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'"/>
    <button type="button" name="div" onclick="borrar(this.parentNode)">borrar</button>
</div>
Lo de usar listas (que según tú es más sencillo) es que no sé a qué te refieres, porque llevo poco usando javascript y nunca lo he usado... ¿debería usarlas en vez de ésto?.

Muchas gracias de nuevo :))
  #8 (permalink)  
Antiguo 24/08/2008, 20:20
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Ups, es cierto. No me había percatado de que los hijos no se crean al final de la lista de hijos. A ver cómo lo solventamos.

Tu ejemplo está bien, ya empieza a ser lo que debería ser.

Lo de usar listas me refería a usar etiquetas UL y LI, que es lo que necesitamos en este caso y intentamos esquivar con los DIVs.

El onclick="foco=this" sería más lógico poner onfocus="foco=this"; pero veo que nos va a dar problemas, así que mejor sacrificar esa parte.

Te propongo la modificación de que la caja que actualmente tiene el foco cuando pulsemos el botón para crear, mantenga el foco. Creo que es más intuitivo. Así podemos darle varias veces al botón directamente para crear más hijos.


Creo que podría ser así:
Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<
head>
<
meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<
meta name="Author" content="derkeNuke" />
<
title>Página nueva</title>
<
style type="text/css">

</
style>
</
head>

<
body>

<
div>
  <
div align="center">
      <
input type="button" value="capitulo" name="capitulo" onclick="seleccionados()"/>
  </
div>
</
div>


<
div>
  <
div id="fiel" align='left' >
    <
input type="text" name="cap3" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'"/>            
  </
div>
</
div>  

<
div id="modulo" style="display:none">
    <
input type="text" name="cap" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'" value="" />
    <
button type="button" name="div" onclick="borrar(this.parentNode)">borrar</button>
</
div>


<
script type="text/javascript">
<!--

function 
insertAfter(nodereferenceNode) {
    
referenceNode.parentNode.insertBefore(nodereferenceNode.nextSibling);


var 
foco=0;
function 
seleccionados(){
    if(
foco!=0){
           var 
fi document.getElementById('fiel'); // 1
        
var copia document.getElementById("modulo").cloneNode(true);
        
copia.style.display "block";

        var 
nuevoMargenanteriorMargin parseInt(foco.parentNode.style.marginLeft) || 0;
        
copia.style.marginLeft = (nuevoMargen=anteriorMargin+2) +"em";

        
// tendremos que recorrer todos los hermanos siguientes (nextSibling) que tengan como margen nuevoMargen (o más) para saber dónde está el último "hijo". Éste es el problema de no hacerlo con listas, que tenemos que hallar manualmente la jerarquía
        
var despuesDe foco.parentNode;
        while( (
despuesDe.nextSibling) && (parseInt(despuesDe.nextSibling.style.marginLeft) || 0) >= nuevoMargen )
            
despuesDe despuesDe.nextSibling;
        
insertAfter(copiadespuesDe);
        
         
//fi.appendChild(copia);
        
        
foco.focus();            // le devolvemos el foco tras pulsar el botón
    
}
    
//foco=0;
}


// -->
</script>

</body>
</html> 

Esto evoluciona.



Saludos.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #9 (permalink)  
Antiguo 25/08/2008, 02:10
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 1 mes
Puntos: 1284
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola:

Con respecto a insertAfter, ya hemos hablado del asunto en este tema: insertBefore no: quiero un insertAfter!... o sea un alias mejor sería:

Código:
function insertAfter(nodo, elemento)	{
	with(elemento.parentNode)
		(lastChild == elemento) ? appendChild(nodo) : insertBefore(nodo, elemento.nextSibling);
}
Tan solo varía en controlar la existencia del nextSibling.

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #10 (permalink)  
Antiguo 25/08/2008, 03:06
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola de nuevo!

La jerarquía ya funciona ( aunque no entiendo la solución de Caricatos he probado el último código de derkenuke con su insertAfter y con el insertAfter de Caricatos y funciona perfectamente, o eso creo, con los dos ... ). Lo siento, pero ya llega esto a un nivel en el que me pierdo :(

Ahora estoy con el borrar, supongo cualquiera de los input tendré previamente que darle identificadores no? bueno voy a ver que consigo...

Pero quería aprovecha para preguntaros si sabeis la forma de que pueda funcionar en firefox... es que lo he probado y no hace nada.

Muchísimas gracias por vuestra ayuda, espero que podais seguir ayudandome hasta que lo termine... es que es la última parte que me queda (aunque probando me pueden surgir luego más problemas), pero la que más me va a costar
  #11 (permalink)  
Antiguo 25/08/2008, 03:18
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 1 mes
Puntos: 1284
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola:

Pues mi alternativa está pensada en insertar elementos considerando que no exista un elemento "nextSibling", entonces en vez de usar insertBefore (del nextSibling), como este no existe debe usarse appendChild, o sea insertar al final.
Tal vez no sea tu caso y por lo tanto te sirva sin ese control, pero creo que controlar esa existencia el más óptimo.

Sobre borra tienes algo en las FAQs... consiste en obtener el elemento y borrarlo desde el elemento padre...
Código:
elemento = document.getElementById("ejemplo");
elemento.parentNode.removeChild(elemento);
Sobre firefox, es posible que se cancele el script por algún otro error porque el código es válido (si no se me escapó nada)... mira en la consola de errores de ese navegador.

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #12 (permalink)  
Antiguo 25/08/2008, 03:44
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Cita:
Iniciado por caricatos Ver Mensaje
Hola:

Pues mi alternativa está pensada en insertar elementos considerando que no exista un elemento "nextSibling", entonces en vez de usar insertBefore (del nextSibling), como este no existe debe usarse appendChild, o sea insertar al final.
Tal vez no sea tu caso y por lo tanto te sirva sin ese control, pero creo que controlar esa existencia el más óptimo.

Sobre borra tienes algo en las FAQs... consiste en obtener el elemento y borrarlo desde el elemento padre...
Código:
elemento = document.getElementById("ejemplo");
elemento.parentNode.removeChild(elemento);
Sobre firefox, es posible que se cancele el script por algún otro error porque el código es válido (si no se me escapó nada)... mira en la consola de errores de ese navegador.

Saludos
Gracias de nuevo por contestar.

He solucionado lo de borrar así:

Código PHP:

function borrar(padre) {
    
padre.parentNode.removeChild(padre); // 10



<
div id="modulo" style="display:none">
    <
input type="text" name="cap" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'" value="" />
    <
button type="button" name="div" onclick="borrar(this.parentNode)">borrar</button>
</
div
No sé si es la mejor forma, pero creo que lo hace bien.

Lo de firefox lo tengo que ver, porque necesito que me funcione, voy a invertigar a ver que encuentro... y miraré la consola de errores.

saludos
  #13 (permalink)  
Antiguo 25/08/2008, 04:37
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Como error en la consola me dice que: 'despuesDe.nextSibling.style' no tiene propiedades, y supongo que se refiere a lo que pone en el while:

" parseInt(despuesDe.nextSibling.style.marginLeft) || 0) "

while( (despuesDe.nextSibling) && (parseInt(despuesDe.nextSibling.style.marginLeft) || 0) >= nuevoMargen )
despuesDe = despuesDe.nextSibling;


Creo que es porque la primera vez que entra en el bucle, no tiene valor... no se me parece raro.
  #14 (permalink)  
Antiguo 25/08/2008, 05:16
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Ya funciona en firefox! he añadido delante del while:

if(despuesDe.id== 'fiel')
if(despuesDe.nextSibling)
despuesDe = despuesDe.nextSibling;

para comprobar si el campo seleccionado es el primero.

Ya queda menos... :)
  #15 (permalink)  
Antiguo 25/08/2008, 05:54
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola caricatos!

Gracias por traernos esa funcioncilla, es verdad que nos quedamos con esa. Aunque me parece que hace lo mismo así (así lo verás mejor scorm):
Código PHP:
function insertAfter(nodoelemento) {
    if( 
elemento.nextSibling )    // Si tiene hermano siguiente. Es lo mismo que mirar a ver si es el último: (elemento.parentNode.lastChild == elemento) de la de caricatos
        
elemento.parentNode.insertBefore(nodoelemento.nextSibling);
    else
        
elemento.parentNode.appendChild(nodo);

En Firefox hay error porque también cuenta los nodos de texto como nodos. Así que al hacer nextSibling podemos estar cogiendo una tabulación, que evidentemente no tiene propiedad style al ser nodo HTML. Para que nos entendamos: Sería como un nodo creado con document.createTextNode().

Se soluciona así (o como has posteado tú mientras yo escribía, lo mismo da):
Código PHP:
while( (despuesDe.nextSibling) && (despuesDe.nextSibling.nodeType===1) && (parseInt(despuesDe.nextSibling.style.marginLeft) || 0) >= nuevoMargen )     // Menudo while! 
La función borrar tiene más tema del que parece, porque supongo que cuando borres una caja que contiene "hijos" tendrás que borrar también todos esos "hijos" ¿no? (Bueno, y nietos... y todo lo que "cuelgue" de ella). Hay que volver a hallar la jerarquía. El while será básicamente el mismo, sólo que no podemos ejecutar la acción de borrar dentro del while, tendremos que almacenar los nodos descendientes y borrarlos después:
Código PHP:
function borrar(btnBorrar) {
    var 
nuestroDiv descendiente btnBorrar.parentNode

    
// hallemos todos los nodos descendientes (hijos, nietos...) del actual
    
var margenMayor = (parseInt(nuestroDiv.style.marginLeft) || 0) + 2;
    var 
descendientes = [];
    while( 
        (
descendiente descendiente.nextSibling) &&                                // si tiene hermano siguiente
        
(descendiente.nodeType===1) &&                                                // si el hermano siguiente es tipo 1 (nodo HTML)
        
((parseInt(descendiente.style.marginLeft) || 0) >= margenMayor) ) {            // si el hermano siguiente está identado con respecto a nuestroDiv
            
descendientes.push(descendiente);                                            // lo añadimos a la lista para borrarlo
    
}

    
// eliminémoslos
    
for(var i=descendientes.lengthi--; ) 
        
descendientes[i].parentNode.removeChild(descendientes[i]);

    
// eliminemos el actual
    
nuestroDiv.parentNode.removeChild(nuestroDiv); // 10

Código PHP:
<button type="button" name="div" onclick="borrar(this)">borrar</button
Bien lo podríamos haber puesto todo en un whale-while:
Código PHP:
    while( (descendiente descendiente.nextSibling) && (descendiente.nodeType===1) && ((parseInt(descendiente.style.marginLeft) || 0) >= margenMayor) && (descendientes.push(descendiente)) ); 
Pero aunque parezca mentira, me gusta la legibilidad. Sólo que en este caso no he encontrado manera de escribirlo de manera más fácil (enrevesado que llega a ser uno).

Así lo he resuelto bien tanto el FF3 como en IE6. No sé si va funcionando en IE7, espero que sí. No estaría mal meter un confirm() ya que cuando borremos esos datos no tendremos manera de recuperarlos (me ha pasado en pruebas y me fastidiaría bastante en una página real).

También me he dado cuenta de que el valor de las cajas creadas es el mismo que el valor de la primera que insertamos. No sé si será consecuencia de los atributos id y name, pero sería bueno reiniciar el value por si acaso.



Creo que ahora sólo queda ocuparnos de los atributos id y name y probarlo a ver si se envía correctamente ¿no? ¿Qué más te gustaría hacer?
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #16 (permalink)  
Antiguo 25/08/2008, 07:45
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Me siento como trabajando en un grupo en una empresa jejeje. Como siempre digo Muchas gracias.

La función de borrar es perfecta, le he añadido el confirm y queda mucho más profesional.

Cita:
Iniciado por derkenuke Ver Mensaje
También me he dado cuenta de que el valor de las cajas creadas es el mismo que el valor de la primera que insertamos. No sé si será consecuencia de los atributos id y name, pero sería bueno reiniciar el value por si acaso.

Creo que ahora sólo queda ocuparnos de los atributos id y name y probarlo a ver si se envía correctamente ¿no?
Respecto a ésto que dices... no se exactamente a qué te refieres, el nombre del primer input es 'cap3' (lo cambiaré a título que queda mejor), y el nombre de los siguientes, los que se agregan, si son iguales, y es 'cap'. No se si te referías a eso...

Pero he hecho un cambio y una prueba: Lo que se añaden nuevos, los llamo así:

Código PHP:
<input type="text" name="cap[]" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'" value="" /> 
Vamos que ahora se llaman 'cap[]'. Además lo he metido todo en un formulario y he puesto un botón 'Enviar' para probar que puedo mostrar los valores. He puesto en PHP:

Código PHP:
if($enviar){
    foreach(
$cap as $c)
        echo 
$c;    
  } 
Y muestro todo lo que escribo en los inputs (emnos el primero que tendría que poner echo $cap3;).

Para acceder desde javascript bastaría (o eso creo) con poner:

Código PHP:
for(var i=0;i<formulario['cap[]'].length;i++){
  
alert(formulario['scorms[]'][i].value); 
Lo último no lo he probado. Así que imagino que no habrá problemas cuando lo quiera tratar.

Y respecto a
Cita:
¿Qué más te gustaría hacer?
uffff queda todavía algo complicado, espero no desanimaros...jejeje

Tengo en un fichero aparte ( que quiero juntar con éste) código que lo que hace es coger unos valores que están en una variable de sesión (que serán los recursos que puede elegir el usuario) y los pone en unos div con propiedades drag&drop, vamos que puedo arrastraslos y cambiarlos de orden y eso. Lo que me gustaría es, que al pulsar un botón 'Add recurso', se añada 'algo' a la jerarquía que tenemos (siempre teniendo en cuenta que el usuario, como hasta ahora, tiene que pulsar el input text del que quiere que cuelgue el recurso, y que tiene que ser un input que no tenga hijos, vamos que tienen que ser los últimos de cada rama).

Ese 'algo' he pensado que podría ser otro 'div' para que pueda arrastrar los div de los recursos y ponerlos bonitos en la jerarquía.

¿ Se entiende ? Me lio mucho explicando las cosas.

Os lo dejo explicado, por si alguna idea de las que tengo la veis imposible, porque siempre me quedará la posibilidad de numerar los recursos, y que al pulsar el 'Add recurso' aparezca otro input text pequeño dd el usuario pueda poner el número de recurso que quiere asociar, y quito todo lo de arrastrar. Pero es que con lo que me estais ayudando me emociono y no veo nada imposible :)

Pues eso, que voy a ver si uno los dos ficheros y muestro a un lado la jerarquía y a otro los recursos... si creeis que es mejor que empiece por otro lado...
  #17 (permalink)  
Antiguo 25/08/2008, 08:12
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 1 mes
Puntos: 1284
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola:

Hay un par de cosas que no me cuadran... (la verdad es que no lo he visto con detenimiento porque tengo que irme, pero voy a soltar mi duda)

Que un nodo de texto sea un nodo ya lo sé, y entonces nunca pasaría por el appendChild, y no debería haber poblemas... ... (me refiero a la inserción)

Lo de borrar nodos con hijos, tampoco creo que haya problemas (me parece que no hay que controlar nada porque se borran sin más).

Y me pareció ver algo de eventos en nodo de texto... (volveré a revisar el tema luego)... Los manejadores solo se asignan a nodos etiquetas... creo que estoy un pelín liado

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #18 (permalink)  
Antiguo 25/08/2008, 08:38
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Te refieres al onFocus onBlur en los input text??? realmente no se si se puede hacer eso, pero o hacen nada a parte de darle color de fondo al input, para que el usuario 'vea' que está seleccionado...

Espero que sea eso a lo que te refieres caricatos, no me asustes jejeje Esperaba que ese código ya lo tuvieramos bien.

Que ahora estoy con el drag&drop...
  #19 (permalink)  
Antiguo 25/08/2008, 09:27
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola de nuevo,

he buscado un código nuevo de drag drop porque el qu tenía no me movía las capas por toda la pantalla, sino que las cambiaba de orden en la capa contenedora. Ahora con éste nuevo código no necesito capa contenedora, el problema es que debería servir para firefox, pero a mi no me funciona... me da 'error al leer el valor para la propiedad top y para la propiedad left'.

Las líneas que usan top y left son:

tx = parseInt(dobj.style.left + 0,10);
ty = parseInt(dobj.style.top + 0,10);

De todas formas os dejo en enlace del código:

http://www.codigojavascript.com/imag...enes-mouse.php

Voy a seguir a ver si veo el problema, pero ponía que debía funcionar...
  #20 (permalink)  
Antiguo 25/08/2008, 09:58
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Buf, mucho avanza el hilo en poco tiempo.

Muchas cosas que responder.

Cita:
Iniciado por caricatos Ver Mensaje
Lo de borrar nodos con hijos, tampoco creo que haya problemas (me parece que no hay que controlar nada porque se borran sin más).
La función de borrar() tiene tejemaneje porque todos los hijos no están en un DIV. Todos los DIVs que se añaden, si son hijos como si no, son DIVs clónicos, iguales. La única cosa que diferencia a un DIV padre de un DIV hijo es el marginLeft. Por eso hay que hallar la jerarquía con bucles while. Es un poco lioso, y casi sería mejor hacerlo con listas; pero ya lo tenemos casi hecho así. Con listas sólo habría que mirar si el siguiente elemento LI contiene un UL:
Código HTML:
<ul>
	<li id="1">caja+boton</li>
	<li id="2">caja+boton</li>
	<li id="hijos_de_2">
		<ul>
			<li>caja+boton</li>
			<li>caja+boton</li>
			<li>caja+boton</li>
			<li>
				<ul>
					<li>caja+boton</li>
					<li>caja+boton</li>
					<li>caja+boton</li>
				</ul>
			</li>
			<li>caja+boton</li>
		</ul>
	</li>
</ul> 
Así, si borrasemos el LI de id="2", sólo tendríamos que borrar el LI con id="hijos_de_2" y todo se iría a freir espárragos automáticamente. Con DIVs tenemos que recorrerlos uno a uno comprobando que son hijos para almacenarlos en un array que más tarde será recorrido y elemento a elemento será eliminado.

Cita:
Iniciado por caricatos Ver Mensaje
Y me pareció ver algo de eventos en nodo de texto... (volveré a revisar el tema luego)... Los manejadores solo se asignan a nodos etiquetas... creo que estoy un pelín liado
Espero que no hayamos escrito eso... creo!

Cita:
Iniciado por scorm Ver Mensaje
Respecto a ésto que dices... no se exactamente a qué te refieres
Me refiero a lo siguiente: Nos ponemos en la caja de texto que viene en el documento. Le damos al botón varias veces para crear varias cajas. A esas cajas les escribimos valores: 1,2,3,4 y 5, por ejemplo. Luego nos posicionamos en cualquiera de ellas y le damos al botón para crear nuevas cajas hijas. Cualquier caja que creemos a partir de ese momento tendrá como valor 1.

Cita:
Iniciado por scorm Ver Mensaje
Pero he hecho un cambio y una prueba: Lo que se añaden nuevos, los llamo así:

Código PHP:
<input type="text" name="cap[]" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'" value="" /> 
Vamos que ahora se llaman 'cap[]'.
Sí, es una buena manera de solucionarlo.


Cita:
Iniciado por scorm Ver Mensaje
Además lo he metido todo en un formulario y he puesto un botón 'Enviar' para probar que puedo mostrar los valores. He puesto en PHP:

Código PHP:
if($enviar){
    foreach(
$cap as $c)
        echo 
$c;    
  } 
Y muestro todo lo que escribo en los inputs (emnos el primero que tendría que poner echo $cap3;).
Bien, perfecto. ¿Te manda también el que esta en DIV id="modulo"? ¿Puedes volver a obtener la jerarquía en PHP o eso no te interesa? Ahora mismo no se me ocurre cómo lo haría con esos name's.

Cita:
Iniciado por scorm Ver Mensaje
Y respecto a uffff queda todavía algo complicado, espero no desanimaros...jejeje
(...)
Todo eso que comentas del drag & drop y tal quizás podría ser tema de un nuevo hilo una vez hayamos finiquitado bien este tema. Creo que ya son muchos posts para esto, al final acabaremos con toda tu página web aqui! jeje.


Un saludo
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #21 (permalink)  
Antiguo 25/08/2008, 10:09
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Sí, abriré otro post, aunque antes estoy viendo una librería de drag-n-drop para ver que saco, así que hasta que no abra otro tema, el drag drop está parado...

No sé porqué me da, que cd le haya añadido el drag and drop voy a acabar poniendo la estructura como dices tú, con las listas porque esto va a ser mi lioooso.

Queda algo más en éste tema?? Probando el código, elimina e insertar bien. Al sacar los datos en PHP como puse anteriormente tambien los devuelve bien... lo que no sé es si despues voy a saber cual es cual y asociarlos a los recursos... pero confío en que sí.

Se me escapa algo? o lo cerramos? [es una manera de hablar porque no sé como se cierra un tema] :)
  #22 (permalink)  
Antiguo 25/08/2008, 10:15
Avatar de caricatos
Moderador
 
Fecha de Ingreso: abril-2002
Ubicación: Torremolinos (Málaga)
Mensajes: 19.607
Antigüedad: 22 años, 1 mes
Puntos: 1284
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Cita:
Iniciado por scorm Ver Mensaje
...
Se me escapa algo? o lo cerramos? [es una manera de hablar porque no sé como se cierra un tema] :)
¡je, je! Los temas solo podemos cerrarlos los moderadores, así que no te preocupes que con no seguir posteando es bastante, pero tampoco creo que sea bueno cerrarlo inmediatamente por si hay más aportes.

Y sigue el consejo de derkenuke de abrir temas nuevos para preguntas nuevas.

Saludos
__________________
Por favor:
No hagan preguntas de temas de foros en mensajes privados... no las respondo
  #23 (permalink)  
Antiguo 25/08/2008, 14:37
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Pues si, además a lo mejor tengo que volver a escribir más adelante, cuando tenga que leer los datos...

Ya he abierto el otro tema de drag & drop.

Por si no necesito escribir de nuevo en éste tema pues que nada que muchiiiiiiiiiisimas gracias a los dos :)
  #24 (permalink)  
Antiguo 25/08/2008, 16:10
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 7 meses
Puntos: 45
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Hola:

De nada scorm, a veces me pico con un tema y.. pasan estas cosas.


Bueno, me apetecía hacerlo también con listas. Si no lo hacía me iba a quedar con la espina, así que lo he traído aquí:

Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<
head>
<
meta http-equiv="Content-type" content="text/html;charset=iso-8859-1" />
<
meta name="Author" content="derkeNuke" />
<
title>Página nueva</title>
<
style type="text/css">

</
style>
</
head>

<
body>

<
div>
  <
div align="center">
      <
input type="button" value="capitulo" name="capitulo" onclick="aniadir()"/>
  </
div>
</
div>

<
form action="recibidorGET.php" method="GET">
    <
ul id="fiel">
        <
li>
            <
input type="text" name="cap[]" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'"/>        
        </
li>
    </
ul>
    <
button type="submit">Enviar</button>
</
form>


<
ul id="modulo" style="display:none">
    <
li>
        <
input type="text" name="cap[]" onclick="foco=this" style="background-color: #eeeeee" onfocus="this.style.backgroundColor = '#cccccc'" onblur="this.style.backgroundColor = '#eeeeee'" value="" />
        <
button type="button" name="div" onclick="borrar(this)">borrar</button>
    </
li>
</
ul>


<
script type="text/javascript">
<!--

function 
insertAfter(nodoelemento) {
    
with(elemento.parentNode)
        (
lastChild == elemento) ? appendChild(nodo) : insertBefore(nodoelemento.nextSibling);
}

function 
hermanoSiguienteNoTexto(nodotagName) {
    
nodo nodo.nextSibling;
    while( 
nodo && (nodo.nodeType===|| (nodo.nodeType===&& nodo.tagName.toLowerCase()!=tagName.toLowerCase() )) ) {
        
nodo nodo.nextSibling;
    }
    if( 
nodo ) return nodo;
    else return 
null;

}

var 
foco=0;
function 
aniadir(){
    if(
foco!=0){

        var 
copia document.getElementById("modulo").getElementsByTagName("LI")[0].cloneNode(true);

        var 
actualLI foco.parentNode;
        var 
actualUL actualLI.parentNode;

        
copia.getElementsByTagName("INPUT")[0].name actualLI.getElementsByTagName("INPUT")[0].name +"[]";

        try {                        
// Intentamos añadir el elemento a la lista de hijos, pero si no existe la creamos
            
hermanoSiguienteNoTexto(actualLI"LI").getElementsByTagName("UL")[0].appendChild(copia);
        } catch(
err) {                // Creamos un LI después del actual con un UL que contendrá los hijos
            
var nuevoLI document.createElement("LI");            // siguiente LI
            
var nuevoUL document.createElement("UL");            // lista de hijos
            
nuevoUL.appendChildcopia );            // UL contendrá nuestro elemento caja+boton
            
nuevoLI.appendChild(nuevoUL);            // LI contiene a ese UL
            
insertAfter(nuevoLIactualLI);            // insertamos ese LI despues de nuestro LI
        
}

        
foco.focus();                                // le devolvemos el foco tras pulsar el botón
    
}
}


function 
borrar(btnBorrar) {
    
    var 
actualLI btnBorrar.parentNode;
    var 
actualUL actualLI.parentNode;

    try {        
// Intento borrar todo el LI que contiene lal lista UL de hijos. Si no existe ese UL es que no tiene hijos.
        
var siguienteLI hermanoSiguienteNoTexto(actualLI"LI");
        if( 
siguienteLI.getElementsByTagName("UL")[0] );            // si no tiene salta aquí la excepción
            
actualUL.removeChildsiguienteLI );    
    } catch( 
err ) { }
    
    
actualUL.removeChildactualLI );

}

// -->
</script>

</body>
</html> 
El código javascript se simplifica, se hace más legible. Intentamos una cosa con el try, y si no cuela, hacemos otra cosa con catch. Es más intuitivo así.

Desde luego el borrar() es mucho más fácil.

He puesto esta línea en aniadir() para los name:
copia.getElementsByTagName("INPUT")[0].name = actualLI.getElementsByTagName("INPUT")[0].name +"[]";
Que lo que hace es añadir un "[]" al final del name si es hijo de alguien, por aportar algo de estructura a el envío de datos. Creo que si no tendríamos un problema serio con el envío de datos. De hecho lo tenemos ya, pero supongo que PHP lo sabrá solventar (yo no sé si sería tan capaz...).

Una estructura tan simple como esta:
Código:
+ padre
    |
    +-- 1
    +-- 2
    |   |
    |   +-- a
    |   +-- b
    |   +-- c
    +-- 3
    +-- 4
Devolvería este revoltijo de arrays:
Código PHP:
Array
(
    [
cap] => Array
        (
            [
0] => padre
            
[1] => Array
                (
                    [
0] => 1
                
)

            [
2] => Array
                (
                    [
0] => 2
                
)

            [
3] => Array
                (
                    [
0] => Array
                        (
                            [
0] => a
                        
)

                )

            [
4] => Array
                (
                    [
0] => Array
                        (
                            [
0] => b
                        
)

                )

            [
5] => Array
                (
                    [
0] => Array
                        (
                            [
0] => c
                        
)

                )

            [
6] => Array
                (
                    [
0] => 3
                
)

            [
7] => Array
                (
                    [
0] => 4
                
)

        )

    [
div] => borrar

Y bueno, la estructura se ve en la profundidad de los arrays, sólo queda limpiarla bien... He intentado poner índices en los name con javascript, pero queda muy sucio.

Quédate con la opción que más te guste.


Un saludo.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #25 (permalink)  
Antiguo 25/08/2008, 18:20
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Poner <input type="text" en diferentes partes al pulsar un botón

Sin palabras!!!

Gracias de nuevo, lo probaré más adelante...y si te quieres picar tambien con mi problema de drag & drop...tienes mi permiso :)

Ya en serio, gracias de nuevo y tranquilo que lo del drag-drop sería abusar jejeje

Aunque no te estrañe que tenga que volver a este tema para hacerle cambios...

Nos vemos por el foro
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 00:38.