Ejemplo de Drag and Drop jQuery con PHP y MySQL

Continuando con los ejercicios de jQuery aquí les traigo un ejemplo para trabajar con drag and drop de jQuery combinándolo con PHP y una base de datos MySQL, el ejercicio consiste en registrar a un alumno y los idiomas que esté domina, para seleccionar dichos idiomas utilizaremos drag and drop.

fdragdrop

BASE DE DATOS

En la base de datos vamos a trabajar con 3 tablas: tblalumno, tblidioma y alumnoidioma


-- -----------------------------------------------------
-- Tabla: tblalumno
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `tblalumno` (
 `idalumno` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
 `paterno` VARCHAR(15) NOT NULL ,
 `materno` VARCHAR(15) NOT NULL ,
 `nombre` VARCHAR(15) NOT NULL ,
 PRIMARY KEY (`idalumno`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Tabla: tblidioma
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `tblidioma` (
  `ididioma` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `idioma` VARCHAR(15) NOT NULL ,
  PRIMARY KEY (`ididioma`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Tabla: alumnoidiomas
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `alumnoidiomas` (
 `idalumno` INT UNSIGNED NOT NULL ,
 `ididioma` INT UNSIGNED NOT NULL ,
 PRIMARY KEY (`idalumno`, `ididioma`) ,
 INDEX `fk_alumnoidiomas_tblAlumno_idx` (`idalumno` ASC) ,
 CONSTRAINT `fk_alumnoidiomas_tblAlumno`
 FOREIGN KEY (`idalumno` )
 REFERENCES `tblalumno` (`idalumno` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION,
 CONSTRAINT `fk_alumnoidiomas_tblidioma1`
 FOREIGN KEY (`idalumno` )
 REFERENCES `tblidioma` (`ididioma` )
 ON DELETE NO ACTION
 ON UPDATE NO ACTION)
ENGINE = InnoDB;

ARCHIVO: index.php

En este archivo vamos a tener el formulario de captura, el código para el drag&drop y el código para enviar mediante ajax la información del alumno, al final va a mostrar un mensaje indicando si la información se guardó o no. Una vez explicada la función de este archivo comenzamos con el código HTML para crear el formulario de captura.

CODIGO HTML

<div id="informacion">
    <form id="frmAlumno"><label for="paterno">Paterno</label>
        <input id="paterno" type="text" name="paterno" value="" />
        <label for="materno">Materno</label>
        <input id="materno" type="text" name="materno" value="" />
        <label for="nombre">Nombre</label>
        <input id="nombre" type="text" name="nombre" value="" />
        <label>Selecciona los idiomas que el alumno domina</label>
        <ul id="idiomasseleccionados"></ul>
        <ul id="idiomas"></ul>
        <input type="submit" name="enviar" value="Enviar" />
    </form>
</div>

Como podemos ver se crean los controles de tipo input para la captura del apellido paterno, materno y nombre del alumno, para agregar los idiomas con drag and drop se utilizaran dos listas no ordenadas cada una con su respectivo atributo id

  • idiomasseleccionados va a tener la lista de idiomas que el alumno domina
  • idiomas va tener la lista de idiomas disponibles

al final encontramos el botón para enviar el formulario.

CODIGO CSS

Podemos agregar algo de CSS para modificar la apariencia del formulario, hay que recordar que dicha información la podemos colocar con una etiqueta <style> dentro de la etiqueta <head> o en un archivo externo enlazado con la etiqueta <link>

        #informacion{
        	width:500px;
        	margin: 0 auto;
        }

        form{
        	width:47s8px;
        	border:1px solid #ddd;
        	padding:10px;
        	float:left;
        }

        form label{
        	width:100%;
        	float:left;
        	margin: 5px 0;
        }

        form input{
        	float:left;
        	margin: 5px 0;
        }

        ul{
        	width:200px;
        	float:left;
        	border:1px solid #ddd;
        	margin:5px;
        	padding:10px;
        	list-style-type: none;
        }

        li{
        	margin:5px 0;
        	background:#ddd;
        	cursor:move;
        	padding:5px;
        	list-style-type: none;
        }

CODIGO PHP

Una vez que ya tenemos el código HTML y CSS lo sigue es agregar una pequeña parte de código PHP para que cuando la pagina cargue ya aparezca  la lista de idiomas disponibles.

La primer linea la colocamos al principio del archivo y es un require_once para enlazar otro archivo llamado cargaridiomas.php

<?php
    <require_once('cargaridiomas.php');
?>

La segunda parte del código PHP para este archivo la colocamos dentro de la lista con el atributo id=”idiomas”, de esta forma la lista se llena cuando se carga la página.

<ul id="idiomas">
    <?php echo cargaridiomas(); ?>
</ul>

ARCHIVO: cargaridiomas.php

Creamos el archivo cargaridiomas.php dentro del cual  vamos a escribir una función que se encargue de realizar la consulta a la base de datos y regresar la lista de idiomas disponibles.

<?php
function cargaridiomas(){
    //Conexion a la base de datos
    $conexion = new mysqli('servidor','usuario','contraseña','basedatos',3306);
    //Consulta SQL a ejecutar para obtener los idiomas
    $consulta = "SELECT * FROM tblidioma";
    //Se ejecuta la consulta
    $result = $conexion->query($consulta);
    $respuesta = "";
    //Si se obtuvo algun registro se recorre el resultado
    if($result->num_rows > 0){

        // Ciclo para crear la cadena con la lista de idiomas que va a retornar la funcion
	while($fila = $result->fetch_array()){

            // A cada idioma se le asigna el atributo id, lo vamos a utilizar a la hora de guardar en la base de datos
	    $respuesta .= '<li id="'.$fila['ididioma'].'">'.utf8_encode($fila['idioma']).'</li>';
	}
    }
    // Se regresa la cadena de respuesta
    return $respuesta;
}
?>

Hasta este punto ya esta listo el formulario para la captura, ahora procedemos a añadir el codigo jQuery para el drag & drop dentro del archivo index.php.

ARCHIVO: index.php

CÓDIGO DE jQuery

Para el código jQuery lo primero que hacemos es enlazar las librerías jQuery y jQueryUI con las siguientes lineas que se colocan dentro de la etiqueta <head>


<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>

Una vez que se enlazaron las librerías de jQuery continuamos con la declaración $(document).ready, hay que recordar que con esta declaración el código se va a ejecutar hasta que la pagina este preparada.

DRAG

Comenzamos agregando a los elementos de las listas <li> el widget draggable para que podamos arrastrarlos utilizando el mouse, podemos configurar algunas de sus opciones, para este ejemplo vamos a configurar 2, la primera es appendTo que nos permite indicar a que elemento se va a agregar el elemento seleccionado mientras lo arrastramos en este caso lo añadimos a body. La segunda opción es helper con el valor clone, de esta forma se crea un duplicado del elemento, el elemento original se queda en su misma posición y se arrastra el duplicado.

$(document).ready(function(){
    $( "#idiomas li, #idiomasseleccionados li" ).draggable({
        appendTo: "body",
	helper: 'clone',
    });

Hay que notar que la opción de arrastrar la vamos a aplicar a las dos listas, por lo tanto para no duplicar el código colocamos los 2 selectores separados por una coma $( “#idiomas li, #idiomasseleccionados li” )

DROP

Ahora pasamos con el código para los elementos que va a ser los contenedores en este caso las listas con los atributos id=”idiomasseleccionados” e id=”idiomas”, al igual que el anterior para no duplicar el código de las dos listas colocamos ambos selectores separados por una coma y configuramos algunas de sus opciones: accept: Indica que elementos se pueden agregar al contenedor, en este caso solo vamos a aceptar elementos de lista <li>, activeClass: Permite asignar a los elementos droppables una clase mientras estamos arrastrando algún elemento, hoverClass: Permite agregar a los elementos droppables una clase mientras tengamos arrastrando un elemento encima de este. Por ultimo añadimos el evento drop para agregar el elemento que arrastramos hacia la lista correspondiente

$( "#idiomasseleccionados, #idiomas" ).droppable({
    accept:'li',
    activeClass: "ui-state-default",
    hoverClass: "ui-state-hover",

    drop: function( event, ui ) {
        ui.draggable.appendTo(this).fadeIn();
    }
});

En el ejemplo a las opciones activeClass y hoverClass le agregamos una clase predefinida del CSS de jQueryUI pero podemos poner los nombres de las clases que queramos y en nuestra hoja de estilo definimos las reglas CSS correspondientes.

ENVIAR FORMULARIO CON AJAX

En este punto enviamos mediante ajax los campos del formulario para guardarlos en la base de datos, para no extender mas este tutorial solo colocare los comentarios en el código y me enfocare mas a la forma en que obtenemos la lista de idiomas seleccionados.

$("#frmAlumno").submit(function(){
    //Funcion para obtener los valores del formulario se explica mas adelante
    datos = obtenerDatos();
    $.ajax({
    	url:'guardarAlumno.php', //URL del archivo php que procesa la petición. Se explica mas adelante
    	type:'post', // Los datos se envían mediante el método POST
    	dataType:'json', // La respuesta se obtiene como JSON
    	data:datos // Los datos del formulario
    }).done(function(respuesta){
        //Condición para verificar si se guardaron o no los datos
        if( respuesta.estado == true )
            alert("La información se guardó correctamente");
        else
    	    alert("Ocurrió un error al guardar la información, por favor vuelve a intentarlo");
    });
    return false; // Se regresa false para el que submit no se ejecute.
});

FUNCIÓN PAR OBTENER LOS DATOS DEL FORMULARIO

Esta función la utilizamos para obtener los datos del formulario y los idiomas seleccionados de la lista, para lo cual seleccionamos todos los elementos li que se encuentren dentro de un elemento con id=”idiomasseleccionado” y los recorremos utilizando el metodo .each, al final obtenemos una cadena con los id’s de los idiomas seleccionados separados por una coma.
Añadimos todos los datos a un arreglo key:valor y es lo que regresa la función.

function obtenerDatos(){
    //Se crea la variable para la lista de idiomas seleccionados
    var idiomas ="";
    //Se obtiene todos los elementos li de la lista con id="idiomasseleccionados" y se recorren
    // utilizando el método .each
    $( "#idiomasseleccionados li" ).each(function (i) {
        // Se agrega a la variable idiomas el valor del atributo id y se le agrega una coma al final
        // para separar cada idioma
        idiomas += $(this).attr('id')+",";
    });
    // Se almacenan todos los datos en un arreglo
    datos = [{name:"accion",value:"guardar"},{name:"paterno", value:$("#paterno").val()},{name:"materno", value:$("#materno").val()},{name: "nombre", value:$("#nombre").val()},{name:"idiomas", value:idiomas}];
    // Se regresa la variable datos con toda la informacion del alumno
    return datos;
}

ARCHIVO: guardarAlumno.php

Para terminar el tutorial pasamos al último archivo el cual se encarga de guardar la información en la base de datos, en el código primero recogemos los valores que trae el arreglo $_POST y los asignamos a su variable correspondiente, después se crea un objeto para la respuesta y se realiza la conexión a la base de datos.

<?php
if( isset($_POST['accion']) ){
    // Variables con la informacion del alumno
    $accion = $_POST['accion'];
    $paterno = $_POST['paterno'];
    $materno = $_POST['materno'];
    $nombre = $_POST['nombre'];
    $idiomas = $_POST['idiomas'];
    //Se crea la respuesta del servidor
    $respuesta = new stdClass();
    // Se realiza la conexion con la base de datos
    $conexion = new mysqli('servidor','usuario','password','basedatos',3306);

Debido a que se tienen que ejecutar varias consultas para registrar al alumno y sus idiomas vamos a trabajar con transacciones, por lo tanto autocommit lo ponemos a false de esta forma no se aplica algun cambio hasta que se ejecuta commit  para salvar la informacion o rollback para cancelar todo, despues  ejecutamos la primer consulta para insertar la información en tblalumno

   $conexion->autocommit(FALSE);
   $consulta = "INSERT INTO tblalumno (paterno, materno, nombre) VALUES('$paterno','$materno','$nombre');";

Si la primer consulta se ejecutó correctamente pasamos a la siguiente en la cual insertamos cada uno de los idiomas en la tabla alumnoidiomas, hay que recordar que los idiomas los obtuvimos en una cadena de texto y separador por una coma entonces lo que tenemos que hacer para trabajarlos de forma individual es separarlos en un arreglo con la ayuda de la función explode posteriormente recorremos el arreglo para ejecutar cada una de las consultas, si alguna falla se ejecuta el rollback de la conexión para que ningún cambio desde que iniciamos la transacción se guarde, posteriormente se imprime la respuesta y con die() terminamos la ejecución del código.

    if( $conexion->query($consulta) ){
        //Se obtiene el id del alumno que se insertó
    	$idalumno = $conexion->insert_id;
        // Se elimina la ultima coma de la cadena
    	$idiomas = trim($idiomas,',');
        // Se dividen los valores de la cadena en un arreglo
    	$idiomas = explode(',', $idiomas);
        // Se recorre el arreglo de idiomas
    	foreach ($idiomas as $idioma) {

            $consulta = "INSERT INTO alumnoidiomas (idalumno, ididioma) VALUE($idalumno,$idioma)";
            // Se ejecuta cada consulta para guardar los idiomas
	    if( $conexion->query($consulta) == FALSE ){
                // Se ejecuta este codigo si alguna consulta no se ejecutó correctamente
	    	$respuesta->estado = FALSE;
	    	$conexion->rollback();
	    	echo json_encode($respuesta);
	    	die();
	    }
	}
    }
    else{
        // Este codigo se ejecuta si la primer consula falló
    	$respuesta->estado = FALSE;
    	$conexion->rollback();
    	echo json_encode($respuesta);
        die();
    }

En caso de que todas las consultas se hayan ejecutado correctamente se ejecuta el commit para salvar todos los cambios realizados en la base de datos y se imprime la respuesta que va a recibir el código de Jquery que creamos previamente.

		$respuesta->estado = TRUE;
		$conexion->commit();
		echo json_encode($respuesta);
	}
?>

La respuesta que se envía desde el servidor solo puede tener dos valores estado TRUE cuando se guardo correctamente y FALSE cuando falló alguna consulta.

Bueno eso es todo para este ejercicio, si la información les sirve recomienden el blog y denle clic al botón me gusta de Facebook, más abajo les dejo el link para descargar el ejemplo completo.

download

10 comentarios en “Ejemplo de Drag and Drop jQuery con PHP y MySQL”

  1. Martin dice:

    Podes poner una demo porque estoy intentando que funcione y no funciona??
    Saludos

    1. denker dice:

      Hola Martín puedes descargar el archivo de nuevo, incluí la base de datos que utilice.

      En la linea del javascript donde evalúa la respuesta del servidor se me había ido un “$” de mas.

      esa linea queda así:

      if(respuesta.estado == true)

      Saludos

  2. alberto dice:

    hola una pregunta en el dragdrop como puedo guardar el nombre del idioma porque tu guardas solo el código del idioma y necesito que guarde el nombre para una tarea por favor gracias

    1. denker dice:

      Cuando se crean las opciones del select el value ponlo con el nombre, de esta forma cuando se mande el formulario para guardar ya tendrias el nombre

  3. Esteban dice:

    La explicacion es excelente , lastima que el código no funciona, el formulario no funciona.
    Actualice los datos de coneccion pero asi y todo no puedo hacer que funcione.
    Descargue los archivos y modifique la coneccion asi:
    $conexion = new mysqli(‘localhost’,’root’,”,’Pruebas’,3306);
    pero no he podido hacer que grabe al alumno

  4. JOSEPH dice:

    esta muy bueno el tutorial, un fa me podria decir o explciar como podria hacer una consulta desde el evento, pues ahi muestra un insert y lo hace perfecto, pero quiero que al arrastrar una imagen o una palabra me salga la consulta de la db, muchas gracias.

  5. Mony dice:

    Hola disculpa podrías poner un ejemplo de como usar el drag and drop en una tabla, para reacomodar las columnas por favor!!

  6. pedro dice:

    buenas noches, estoy realizando un horario y tiene secciones de hora y hora se a su vez se segmentan en 5 secciones para lograr intervalos de horas es decir de 7:15 a 8:45 como podría utilizar esto para alcanzar esto y como puedo extraer la información por los segmentos por las cuales paso el ratón para saber cual va hacer el intervalo del horario agradezco su ayuda de antemano si es haciendo la utilización de este método o otro gracias

  7. ujcmjhonjhon dice:

    buenas tardes, utilice tu código funciona muy bien, pero como haría cuando trate de editarlo, porque no lo reconoce cuando.

Deja un comentario