DÍA 18

Edit in Place

Editar registros en el lugar, muchas veces, nos puede facilitar la tarea de realizar pequeñas modificaciones en una gran cantidad de registros sin necesidad de entrar a la edición completa de nuestros datos.


editinplace

Una consulta que recibo habitualmente en mi blog es sobre un viejo artículo que escribí que se llamaba edit in place con PHP. En aquel caso, el artículo convertía las celdas de una tabla de datos html permitiendo la edición siempre contra un campo input de tipo texto.

Esto tenía la ventaja de, como dije, permitir la edición rápida de valores (en aquel ejemplo se trataba de una tabla de personas) y un pequeño código javascript nos daba la posibilidad de modificar sus valores.

Esta vez, he profundizado un poco el código y, si bien sigue siendo casero (es decir no utilizamos plugins en jQuery sino que es código propio y, evolucionando las opciones, he agregado la posibilidad de convertir nuestro texto a editar en una lista de tipo select, en un textarea o, incluso, en un editor de texto enriquecido wysiwyg (what you see is what you get) como es el archiconocido TinyMCE.

Pero bueno, vamos al juego, dejemos las introducciones y vamos a lo que nos gusta, el código…!

Ejemplo 1: Editando HTML

En este caso, lo que vamos a hacer es editar una noticia desplegada presentando el contenido de la misma manera que se mostraría en el frontal de nuestra web si estuviera publicada.

Imaginemos que queremos preparar un CMS que permita a un usuario con muy pocos conocimientos de informática y poco familiarizado con el uso de formularios HTML, y queremos darle la posibilidad de editar el texto que está viendo de la manera exacta en que quedará una vez publicado.

En este caso, lo que vamos a necesitar son los bloques de contenido HTML que será editable de tal manera que podemos definir muy claramente el campo de nuestra base de datos que vamos a editar en cada momento.

De este modo, presentamos el primer bloque:

<div class="edit titulo" data-idnoticia="<?php echo $noticia["idnoticia"]; ?>" data-tabla="noticias" data-condicion="idnoticia" data-tipo="input" data-campo="titulo" data-defecto="<?php echo $noticia["titulo"]; ?>">
    <div class="editable"><?php echo $noticia["titulo"]; ?></div>
    <div class="barra"><a href="#" class="editar">EDITAR</a></div>
</div>

Del bloque anterior nos surgen varios elementos a tener en cuenta que son:

  1. data-idnoticia: se encargará de obtener el ID del registro a editar de la tabla noticias
  2. data-tabla: indicará la tabla mysql que editaremos
  3. data-condicion: indicará el campo usado en la condición where de nuestra consulta sql
  4. data-tipo: indicará el tipo de campo que mostrará al hacer click en edición (tenemos disponible: input, textarea, tinymce y select)
  5. data-campo: indicará el campo a modificar en nuestra tabla mysql
  6. data-defecto: indica el valor por defecto de ese campo (para cuando se aplica la opción de cancelar)

Además, contamos con un div con clase “editable” que contendrá el contenido de nuestra base de datos que será, justamente eso, editable.

Luego, un div con clase “barra” que nos mostrará el botón editar. He optado, en este caso, por poner el botón directamente en el DOM y no crearlo con cada elemento para que quede más claro de dónde sale todo lo que vemos.

Editando en línea estos elementos, tendremos 3 opciones que mostrar (aunque el código permitiría crear nuestras propias condiciones) que son un campo de texto, un textarea/tinymce y un select con diferentes opciones.

El apartado título de la noticia de prueba se editará en el lugar creando un input, el cuerpo usará un editor tinymce y la opción de mostrar u ocultar la noticia mostrará un select list.

Estos pasos deberemos repetirlos tantas veces, una vez por cada campo que necesitemos convertir en editable de nuestra base de datos

Simplemente cambiando el atributo data correspondiente por uno de los que aparecen en el siguiente código javascript asignaremos el tipo de elemento que debe crearse cuando presionemos el botón de EDITAR.

switch(tipo)
{
    case "select":
    var opc=div.data("opciones").split("|");
    var lit=div.data("literales").split("|");
    if (opc && lit)
    {
        var combo=div.data("mostrar")+"<select name='"+campo+"' class='textonuevo'>";
        for (i = 0; i < opc.length; i++) {
            combo+="<option value='"+opc[i]+"'"+(opc[i]==defecto?" selected":"")+">"+lit[i]+"</option>";
        }
        combo+="</select>"+botones;
    }
    editable.html(combo);
    break;
   
    case "textarea":
    editable.html("<textarea name='"+campo+"' class='textonuevo'>"+defecto+"</textarea>"+botones);
    break;

    case "tinymce":
    editable.html("<textarea name='"+campo+"' class='textonuevo mceAdvanced'>"+defecto+"</textarea>"+botones);
    $(".mceAdvanced").tinymce({
        script_url: 'js/tinymce/tinymce.min.js',menubar:false,statusbar: false,relative_urls : false,convert_urls : false,relative_urls: false,remove_script_host: false,mode : "textareas",height:300,theme: "modern",language:"es",plugins: [ "advlist autolink lists link image charmap print preview hr anchor pagebreak","searchreplace visualblocks visualchars code fullscreen","insertdatetime media nonbreaking save table contextmenu directionality","emoticons template paste textcolor filemanager" ],toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | print preview media | forecolor backcolor emoticons",autosave_ask_before_unload: false});
    break;

    default:
    editable.html("<input type='text' class='textonuevo' name='"+campo+"' value='"+defecto+"'>"+botones);
}

Una pequeña llamada ajax a un fichero PHP pasando los parámetros necesarios, se encargará de reflejar los cambios procesados.

Cuando procesamos la modificación, recibiremos una respuesta que, en caso de ser satisfactoria, nos servirá para pisar el contenido por defecto que teníamos en el campo editable para hace un refresco del mismo.

Si por el contrario, quisiéramos cancelar la edición en línea, un botón CANCELAR nos aparecerá destruyendo el campo creado y mostrando el contenido tal como estaba antes de empezar la edición.

Ejemplo 2: Editando una tabla con diferentes valores

Al igual que el ejemplo anterior, en este caso, disponemos de una tabla HTML con diferentes campos de cada registro de nuestra base de datos que podemos convertir en editables.

El ejemplo presenta Departamentos como si fueran categorías y lo que nos permitirá la edición es cambiar rápidamente su nombre sin pasar de pantalla en pantalla.

En este caso, también tenemos una serie de parámetros que crear por cada elemento que deseamos convertir en editable y estos se componen de:

<tr>
    <td><?php echo $fila["idsector"]; ?></td>
    <td class="tdeditable" data-idsector="<?php echo $fila["idsector"]; ?>" data-tabla="sectores" data-condicion="idsector" data-tipo="input" data-campo="sector" data-defecto="<?php echo $fila["sector"]; ?>"><div class="editable"><?php echo $fila["sector"]; ?></div><div class="tdbarra"><a href="#" class="editar">EDITAR</a></div></td>
    <td class="tdeditable" data-idsector="<?php echo $fila["idsector"]; ?>" data-tabla="sectores" data-condicion="idsector" data-tipo="select" data-campo="visible" data-defecto="<?php echo htmlentities($fila["visible"]); ?>" data-opciones="0|1" data-literales="No|Si" data-mostrar="Visible: "><div class="editable">Visible: <?php echo $fila["visible"]; ?></div><div class="tdbarra"><a href="#" class="editar">EDITAR</a></td>
</tr>

El código Javascript se ocupará de casi todo llamando a mismo fichero PHP que teníamos antes para procesar los cambios deseados y reflejarlos en nuestra base de datos.

Demos

He publicado ambas demos online estando en este enlace la edición tipo HTML y en este enlace la edición tipo TABLA.

Por supuesto el código estará disponible para descarga y bajo ninguna licencia. Es decir, que lo puedes utilizar a tu gusto, modificarlo en lo que necesites sin necesidad de mencionar fuentes ni nada (aunque una mención en mi Twitter sería más que bienvenida).

Que necesitamos

Básicamente el proyecto consta de 5 elementos necesarios que son:

  • una base de datos MYSQL (adjunta en la descarga)
  • la librería jQuery en versiones superiores a 1.8
  • un poco de código HTML (adjunto en la descarga) y CSS :)
  • un poco (o mucho) de javascript (adjunto en la descarga)
  • un poco de PHP para la conexión cliente/servidor y el almacenado de datos

Comentarios finales

Un año más tengo el placer de participar de este interesante proyecto que es Octuweb, al cual agradezco tenerme siempre presente (y particularmente este año, la paciencia que han tenido conmigo y mis tiempos de entrega) y he desarrollado este pequeño tutorial esperando que te sea útil.

Si bien he hecho varias pruebas de su funcionamiento, no puedo garantizar que no tenga fallos, por lo que es de vital importancia que no copies y pegues el código para utilizarlo sino que lo uses como base para desarrollar tu propio sistema de edición en el lugar o edit in place que mola más (todo en inglés mola más).

Es probable que el código pueda ser mejorado, simplificado, resumido, etc… pero eso ya te lo dejo a ti. Pondré una pequeña reseña en mi blog para que me dejéis dudas o sugerencias para mejorar este sistema.

Gracias por leerme y, si este código te ayuda a hacer algo mejor o te ahorra, al menos, 5 minutos en algún proyecto, he cumplido mi objetivo :)

Descargar archivos