Ver Mensaje Individual
  #17 (permalink)  
Antiguo 27/08/2008, 19:17
scorm
 
Fecha de Ingreso: julio-2008
Mensajes: 85
Antigüedad: 15 años, 10 meses
Puntos: 2
Respuesta: Usar drag & drop con javascript

En vistas de que he estado intentando lo de que si me he equivocado al poner una capa en su contenedor, pueda volver a arrastrarla a su lugar de origen y no he podido... aquí dejo la solución a la que he llegado, y es poner al lado de cada contenedor un botón borrar ( aparece realmente debajo no se porqué), que lo que hace es devolver a su sitio la capa.

No sé quizas me he liado demasiado... pero me parece la mejor opción... si alguien ve algún problema por favor que me lo diga please jejeje

Código HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<script src="javascript/prototype.js" type="text/javascript"></script>
<script src="javascript/scriptaculous.js" type="text/javascript"></script> 

   
<style type="text/css">

body {
	font-family:Georgia, "Times New Roman", Times, serif;
	font-size:12px;
	color:#666666;
	text-align:center; /*aqui mandamos a centrar todo el contenido*/ 
}

#contenedorppal {
	width:100%; /*ancho total de la pagina 77777777777777antes ponia 600*/ 
	border:1px solid #333333; /*encadeno los 3 atributos claves del borde en una sola linea, ahorrando codigo XD*/ 
	background-color:#FFF8F0;
	margin:10px auto; /*10px arriba y abajo, y auto a los lados, para los navegadores nuevos es suficiente para centrar la pagina*/ 
	text-align:left; /*aqui alineamos todo de nuevo a la izquierda, pero dentro del contenedor*/
	overflow: auto;/*se ajusta a firefox para que se vea bien*/
	overflow-y:hidden; 
	overflow-y:hidden;overflow-x:hidden;
}

#margenDerecho{
	margin:10px; /*para que no se pegue al borde*/ 
	padding:10px; /*algo de relleno*/
	width:230px; /*  este ancho es para que cuadre con el texto*/ 
	 /* height:50px; idem*/ 
	border:1px solid #333333; /*decoracion*/ 
	background-color:#CC6600; /*more*/ 
	float:right; /*lo flotamos a la izquierda*/ 
	display:inline; /*display:inline;(*)*/ 
}

#margenIzquierdo{
	margin:10px; /*para que no se pegue al borde*/ 
	padding:10px; /*algo de relleno*/
	width:auto; /*240 px cambiado para boton borrar  este ancho es para que cuadre con el texto*/ 
	 /* height:50px; idem*/ 
	border:1px solid #333333; /*decoracion*/ 
	background-color:#CC6600; /*more*/ 
	float:left; /*lo flotamos a la izquierda*/ 
	display:inline; /*display:inline;(*)*/ 
}

  .droppable_demo {
    width: 230px;
    height: 40px;
    background: #fff;
    border: 5px solid #ccc;
    margin: 0px 1em 1em 0px;
    text-align: center; }
    
  .droppable_demo.hover {
    border: 5px dashed #aaa;
    background:#efefef; }
    
  .draggable{ 
    cursor:pointer; 
    width:230px; 
    height:40px; 
    background:#7baaed; 
    border:1px solid #333;
    margin: 0 1em 1em 0;
    text-align: center;}
   
</style>

<script type="text/javascript">

function borrar_contenedor(btnBorrar) {
    var nuestroDiv = descendiente = btnBorrar.parentNode;
    var nombre_boton=btnBorrar.name.split('_'); // b + id  datos del botón
     
    var recorrer=nuestroDiv.getElementsByTagName("div");
    for (i=0;i<recorrer.length;i++){
        var nombre_contenedor=recorrer[i].id.split('_'); // cont + id  o  nuevo + id
        if(nombre_contenedor[0]=="cont"){ //si es un contenedor
	        if(nombre_contenedor[1] == nombre_boton[1]){ // si coincide el identificador del contenedor con el identificador del botón pulsado, hay que borrar su contenido
	        	if(recorrer[i].ocupado){// si es el contenedor perteneciente al botón pulsado y está ocupado hay que eliminar el contenido
	
					//hacer una copia del siguiente nodo y despues eliminarlo
					
					var partes_div=recorrer[i+1].id.split('_');
					
			    	var nuevoDiv = document.createElement("DIV");
			    	nuevoDiv.className="draggable";
			    	nuevoDiv.id="bloq_"+partes_div[2];
		            nuevoDiv.appendChild(document.createTextNode(recorrer[i+1].firstChild.nodeValue));
					var posAnt=document.getElementById("margenDerecho");
					posAnt.appendChild(nuevoDiv);
					
					nuevoDiv.elObjDraggable=new Draggable(nuevoDiv, {revert: true});	
					        		
	        		//EN VEZ DE BORRAR EL SIGUIENTE, HACER LAS COMPROBACIONES
	        		recorrer[i+1].parentNode.removeChild(recorrer[i+1]);//elimino el siguiente porque se muestra en orde
	
	        	}
	    	}
	    }
	}
    


}

function confirmar_contenedor(obj){
    if(confirm('¿ Está seguro de que desea eliminar el contenido del contenedor ?')){
    	borrar_contenedor(obj);
    }
}

</script>
</head>
 
<body> 
<form ENCTYPE="multipart/form-data" METHOD="post" name="form">

<div id="contenedorppal">
 
<div id="margenDerecho">
		<?
		
		$drop=5;
	    for($i=1;$i<$drop+1;$i++){?>	
			<div class="draggable" id="bloq_<? echo $i; ?>" align="center">Texto <? echo $i; ?></div>
		<?} //fin for
		 ?>		 	
</div> <!-- fin div margenDerecho -->	
	

 <div id="margenIzquierdo"> 
	<?
	for($k=1;$k<$drop+1;$k++){
		?>
		<div class="droppable_demo" id="cont_<? echo $k; ?>">
	  	</div>
	  	<button type="button" name="b_<? echo $k; ?>" onclick="confirmar_contenedor(this)">borrar</button>
	   <?
	} //fin for
	?>
 </div> <!--  fin div margenIzquierdo  -->  
  
  
  
 <script type="text/javascript">
    var capas=document.getElementById("margenDerecho").getElementsByTagName("div");
    for (i=0;i<capas.length;i++){
		capas[i].elObjDraggable=new Draggable(capas[i].id, {revert: true});
	}
	
	
	var capas_cont=document.getElementById("margenIzquierdo").getElementsByTagName("div");
	for (i=0;i<capas_cont.length;i++){
		Droppables.add(capas_cont[i].id, { 
		    accept: 'draggable',
		    hoverclass: 'hover',
		    onDrop: function(element, dropon) { 
		    		// dropon es el contenedor al que arrastro el 'div'
		    		//element es el div que arrastro
		    	if( !dropon.ocupado ) {
			    	var nuevoDiv = document.createElement("DIV");
			    	nuevoDiv.className="draggable";
		            nuevoDiv.appendChild(document.createTextNode(element.firstChild.nodeValue));
		            
		            
		            //Le pongo identificador único que por si lo necesito, tiene la forma: 
		            // nuevo_idcontenedor_idbloquearrastrado
		            var vector = element.id.split('_'); //obtengo el identificador del div que arrastro
		            var vector_cont = dropon.id.split('_');//obtengo el identificador del contenedor
		            nuevoDiv.id="nuevo_"+vector_cont[1]+"_"+vector[1];
		                        
		            dropon.appendChild(nuevoDiv);
		            element.elObjDraggable.options.revert = false;
		            element.parentNode.removeChild(element);
		            dropon.ocupado = true;
		       
		         }
		         else {
                    alert("Esta casilla está ocupada, usa otra por favor.");
                }
	            
			 }
		  });
	}


  function mostrarValores(){
       var capas_cont=document.getElementById("margenIzquierdo").getElementsByTagName("div");
       for (i=0;i<capas_cont.length;i++){
       	   alert(capas_cont[i].id);
       }
       
       var capas_cont=document.getElementById("margenDerecho").getElementsByTagName("div");
       for (i=0;i<capas_cont.length;i++){
       	   alert(capas_cont[i].id);
       }
  }
  </script>
  
  <input type="submit" value="Seleccionar" name="seleccionar" onClick="mostrarValores();">
  
</div> <!-- fin contenedorppal -->
</form>
</body>
</html> 
Dos preguntillas...una es si sabeis por qué sale el botón debajo y no al lado del div...

Y la otra es que cuando recorro la capa 'margenIzquierdo' me he fijado que si pongo un alert devolviéndome los identificadores, me los devuelve en orden, es decir contenedor1 contenedor2 contenidox contenedor3 contenidoy
para cada contenedor daria su identificador, y si está ocupado, su contenido lo muestra inmediatamente despues, entonces al borrar el contenido de un contenedor, he recorrido los contenedores y ciando he encontrado el contenedor al que hacia referencia el boton pulsado, he borrado el contenido siguiente (sin comprobar que realmente es el que quiero borrar).

Se que si lo compruebo estará mejor... pero ¿realmente existe alguna posibilidad de que eso me de un error? porque si el recorrido es en orden, no cabría esa posibilidad, y así me ahorro algo de código...

Muchas Gracias!!