Drag Drop con script.aculo.us, PHP y MySQL – Parte 2

19
4489

En el artículo anterior vimos que es posible capturar todos los elementos de los bloques div y su ubicación mediante la función JavaScript obtenerElementos(). Entonces nos toca ahora enviar esa cadena de valores a un script PHP para que se encargue de cortarlos en los fragmentos correspondientes a los nombres de los empleados (contratados y despedidos) y guardalos en la base de datos.

Pero antes de eso vamos a modificar la funcion obtenerElementos() para que solo envie la cadena de valores y divida a los elementos de cada bloque por un slash ( / ), esa cadena obtenida la pasamos a una función EnviarDatos() que explicaremos luego. La idea es que la funcion obtenerElementos() envie este tipo de cadena: empleado_1_grupo_1, empleado2_grupo_1 / empleado_1_grupo2, empleado_2_grupo_2

function obtenerElementos() {
 var secciones = document.getElementsByClassName('seccion');
 var alerttext = '';
 var separador = '';
 secciones.each(function(seccion) {
  alerttext += separador + Sortable.sequence(seccion);
  separador = "/";
 });
 EnviarDatos(alerttext);
 return false;
}

Veamos ahora la función EnviarDatos() junto con la función que nos permitirá usar el objeto XMLHttpRequest. En nuestro caso separamos estás funciones en un archivo al que llamamos ajax.js

function Ajax(){
 var xmlhttp=false;
 try {
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 }catch(e){
  try {
   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  }catch(E){
   xmlhttp = false;
  }
 }
 if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  xmlhttp = new XMLHttpRequest();
 }
 return xmlhttp;
}

function EnviarDatos(cadena){
 ajax.Ajax();
 ajax.open("POST", "guardar.php",true);
 ajax.onreadystatechange=function(){
  if (ajax.readyState==4) {
   alert(ajax.responseText);
  }
 }
 ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
 ajax.send("cadena="+cadena)
}

Bueno la función Ajax es la que siempre usamos para crear el objeto XMLHttpRequest. Nos enfocamos en EnviarDatos(), este recibe la cadena que la función obtenerElementos() le paso y lo envia mediante método POST al archivo guardar.php. Cuando el archivo guardar.php acabe su proceso entonces aparecerá un mensaje en un alert.

El archivo que realizará el proceso de guardar, o mas bien dicho modificar las dos tablas es guardar.php, veamos su código:

<?php
 require('conexion.php');
 function ElementosEnBlanco(){
  mysql_query("DELETE FROM contratado");
  mysql_query("DELETE FROM despedido");
 }
 $cadena=$_POST['cadena'];
 $cadenas=explode('/',$cadena);
 $nro_cadenas=count($cadenas);
 $i=0;
 ElementosEnBlanco();
 while($i<$nro_cadenas){
  $elementos=explode(',',$cadenas[$i]);
  $nro_elementos=count($elementos);
  $j=0;
  while($j<$nro_elementos){
   if($elementos[$j]!=""){
    switch($i){
     case 0:
      mysql_query("INSERT INTO contratado(nombre_contratado) VALUES ('$elementos[$j]')",$con);
     break;
     case 1:
      mysql_query("INSERT INTO despedido(nombre_despedido) VALUES ('$elementos[$j]')",$con);
     break;
    }
   }
   $j++;
  }
  $i++;
 }

 echo "Cambios OK";
?>

Veamos lentamente el código mientras explicamos. La idea del proceso es eliminar todos los elementos de las dos tablas y luego volverlas a llenar con los nombres de los empleados en las dos tablas en el orden en que son enviadas. Recuerde que la funcion JavaScript envia una cadena de este formato: elemento1, elemento2 / elemento3, elemento4, elemento5, para grabar cada uno, debe de cortarlos primero por el caracter slash ( / ) y luego por las comas ( , ). Veamos los pasos principales:

  • La función ElementosEnBlanco() se encarga limpiar las tablas.
  • Recibimos el contenido de la variable cadena que la funcion JavaScript EnviarDatos envió.
  • Con explode cortamos la variable $cadena donde encuentre el caracter slash ( / ), por lo tanto pasara a ser un array. Si seguimos el ejemplo expuesto $cadenas sería un array con dos elementos: "elemento1, elemento2" y "elemento3, elemento4, elemento5".
  • Contamos el número de elementos que hay en este array.
  • Nos preparamos para empezar a insertar los valores, empezamos una variable contador $i en 0 y llamamos a la función ElementosEnBlanco().
  • Usamos un bucle para recorrer los elementos del array $cadenas, dentro de este bucle usamos explode para cortar la variable $cadena actual donde encuentre una coma ( , ) y este valor será asignado a la variable $elementos un array también. Nuevamente iniciamos un contador $j en 0.
  • Abrimos otro bucle para recorrer ahora el array $elementos. Dentro de este usamos un if para saber si el elemento esta vacio o no, y también usamos un swicth para saber con que tabla vamos a trabajar.

No es nada del otro mundo, con un poco de ingenio y las herramientas que abundan en la web, como el script.aculo.us y demás librerías, se pueden hacer aplicaciones interesantes y agregarle un valor adicional a nuestro trabajos web. Proximamente estaremos viendo mas sobre script.culo.us así que atentos a los movimientos del blog…

[Ver Ejemplo] [Descargar]

19 COMENTARIOS

  1. Me parece muy interesante y útil este post, lo he empleado para el cms de un sitio para ello amplíe los DIV y les incluí más información. Ahora una pregunta me gustaría poder tener la posibilidad de «cerrar» esos DIV, algo así como se realiza en netvives, es decir poder quitar esos DIV. Como se podría hacer???
    Gracias

  2. Jesus, en el caso de que quiero que sea una sola tabla y se actualizen el orden de los datos, pero sin eliminar sino haciendo un Update.

  3. en ese caso al momento de crear la cadena con los elementos separados por comas, también deberas tener en cuenta el id de cada registro.

    Seria un poquito mas trabajaso por el hecho de que para obtener un elemento de un contenedor, Sortable lo ubica por medio del id del div así que alli es donde, no solo deberas colocar el nombre del registro sino también el id de registro.

  4. Felicidades por esta serie de artículos, son excelentes! feliz

    quería comentar un problema al respecto a ver si alguien puede echarme una mano…

    estoy intentando reproducir el ejemplo de drag ‘n drop con dos divs, en el interior de los cuales habrán div’s con imágenes dentro. La idea es que los dos divs se hagan autoscrollables en el momento en el que la altura del grupo de imágenes sobrepasen el height del div que las contiene. Para éllo, he añadido la property overflow:auto, cosa que ha propiciado que cuando intento realizar el drag de cada una de las imágenes, la pueda arrastrar, pero sólo dentor del div que la contiene, ya que se abre el scroll y no puedo sacarla al otro div.

    Si a alguien se le ocurre algo, le estaría muy agradecido.

    Saludos.

  5. Hola!

    El tutorial éste es buenisimo…

    Ahora tengo una duda: ¿cómo hago si en vez de pasar los elenentos de una lista a otra, pasarlos a listas independientes sin que se expanda o agrande ninguna?

    Saludos.

  6. Enhorabuena!! Está genial el artículo!!

    Me gustaría que, cuando arrastro las cosas, en lugar de quedarse el hueco en blanco en donde se podría colocar, apareciera un recuadro de manera que, sin soltar el objeto, pudieras ver como quedaría en ese hueco.

    ¿Sabría como podría hacerlo?
    Muchas gracias!!

  7. Hola Jesus, hace una raato estoy tratando de correr el ejemplo con mozilla y no puedo!.. con IE7 sale ok.. Muchas gracias por el tutorial, me sirvio un monton en mi trabajo.
    Espero puedas ayudarme ahora!

    El codigo es practicamente igual al que tuyo:

    function neworder() {
    //alert(‘ha entraoo’);
    var secciones = document.getElementsByClassName(‘seccion’);
    var alerttext = »;
    var separador = »;
    secciones.each(function(seccion) {
    alerttext += separador + Sortable.sequence(seccion);
    separador = «/»;
    });
    // alert(alerttext);
    EnviarDatos(alerttext);
    return false;
    }

    function Ajax(){
    var xmlhttp=false;
    try {
    xmlhttp = new ActiveXObject(«Msxml2.XMLHTTP»);
    }catch(e){
    try {
    xmlhttp = new ActiveXObject(«Microsoft.XMLHTTP»);
    }catch(E){
    xmlhttp = false;
    }
    }
    if (!xmlhttp && typeof XMLHttpRequest!=’undefined’) {
    xmlhttp = new XMLHttpRequest();
    }
    return xmlhttp;
    }

    function EnviarDatos(cadena){
    var ajax=Ajax();
    ajax.open(«POST», «guardar.php»,true);
    ajax.onreadystatechange=function(){
    if (ajax.readyState==4) {
    alert(ajax.responseText);
    }
    }
    ajax.setRequestHeader(«Content-Type»,»application/x-www-form-urlencoded»);
    ajax.send(«cadena=»+cadena)
    }

  8. Hola

    También he probado la función obtenerElementos() con Mozilla y no funciona. Alguien tiene alguna respuesta?. Con IE6 no hay problema

    Saludos

  9. Pues excelente solo una pequeña observacion para que jale bien en mozilla hay que hacer

    function obtenerElementos() {
    var secciones = $A(document.getElementsByClassName(‘seccion’));
    //lo que sigue de codigo
    }

  10. Este ejemplo seria aun mejor sino hubiese que apretar el boton guardar; lo voy a modificar para que guarde los cambios de inmediato, pero me sirve como base excelente!!; muchas gracias.

  11. Buenas, la verdad que tu ejemplo es buenísimo, pero me gustaría saber si se puede modificar una cosa.

    En una de las columnas, cuando mueves uno de los elementos, ¿Podria no desaparecer? Querria que pudieras modificar una de las tablas de la bbdd y que la otra en vez de mover el elemento, solo lo copiara.

    Espero que me puedas ayudar.
    Gracias de antemano.

Comments are closed.