Crear un sistema de edición en el lugar

Hacer que los usuarios hagan clic en varias páginas para editar un campo es 1999. En este tutorial, aprenderá cómo crear un sistema de edición en el lugar como el que se encuentra en los sitios populares, como Flickr..


Una palabra del autor

Con todo el zumbido en torno a la Web 2.0, la facilidad de uso es ahora mucho más importante que nunca. Ser capaz de editar algo de contenido sin tener que ir a otra página es algo que muchos usuarios realmente anhelan. Muchos nombres grandes ya están utilizando este patrón con gran efecto. Si has usado Flickr, probablemente lo hayas visto en acción..

Creo que una demo vale más que mil palabras. Pulsa el demo y pruébalo tú mismo..

Hoy vamos a ver cómo implementar esto, lo has adivinado, nuestra biblioteca de JavaScript favorita, jQuery. ¿Interesado? Empecemos de inmediato!

Objetivos de diseño

Antes de comenzar a ver cómo implementar la funcionalidad, aquí hay algunas ideas sobre los objetivos y las decisiones resultantes..

  • Tenemos que dejar que el usuario edite el contenido sin salir de la página. Esto es un hecho.
  • Esto debería funcionar como un todo o fallar como un todo. Cuando JS está deshabilitado, no queremos encontrarnos con extraños caprichos.
  • El usuario debe saber que el contenido es editable. Un sutil cambio de fondo azul debería llamar la atención del usuario sobre esto..
  • Cuando se trata de cómo activar la edición, hay algunas opciones. Podemos dejar que el usuario edite con un clic normal o doble clic. He elegido hacer doble clic, ya que los clics aleatorios se producen a un ritmo menor que los clics aleatorios. Cambiarlo es solo cuestión de cambiar el parámetro en el evento de vinculación.
  • Una forma para que el usuario guarde o descarte las ediciones.
  • Los eventos de guardar o editar se pueden activar de 2 maneras. Eventos del teclado o eventos del ratón. Elegí los eventos del mouse ya que los eventos del teclado carecen de especificidad.
  • Con respecto a los eventos del mouse, puede usar los botones tradicionales o los enlaces habituales. Elegí enlaces sin ninguna razón en particular.
  • El usuario debe poder reanudar la edición incluso si hace clic fuera del cuadro de entrada o sale de la página y vuelve.
  • Además, el usuario debe poder editar tantos campos como sea posible simultáneamente.

Ahora que hemos trazado nuestras necesidades, ahora podemos pasar a cómo vamos a hacer esto.

Plan de acción

Ahora necesitaremos hacer un mapa de lo que se debe hacer en un orden específico.

Paso 1: Tendremos que añadir una clase de editable A cada elemento que necesite esta funcionalidad..

Paso 2: A continuación, tendremos que añadir elementos emergentes a cada elemento editable para llamar la atención sobre el hecho de que el contenido de ese elemento es editable. Agregaremos y eliminaremos los elementos emergentes mediante JavaScript en lugar de CSS. Esto se hace principalmente para dispositivos o navegadores con JavaScript desactivado. No queremos enviarles señales visuales equivocadas..

Paso 3: Cuando se hace doble clic en un elemento editable, necesitamos intercambiar el contenido y reemplazarlo con un cuadro de texto con el texto antiguo..

Paso 4a: Cuando el usuario quiera guardar las ediciones, copie el valor de la entrada en el elemento principal y elimine el cuadro de entrada.

Paso 4b: O cuando el usuario quiera descartar los cambios, reemplace el contenido anterior y elimine el cuadro de entrada.

Estos son los pasos básicos para crear esta funcionalidad. Por supuesto, hay algunas otras cosas pequeñas, pero las explicaré a medida que avanzamos..

Core Markup

El marcado HTML de la página de demostración se ve así.

    Sistema de edición en el lugar, por Siddharth para NetTuts      

Edición in situ

por Siddharth para la gente encantadora en Net Tuts

Elementos con una clase de editable son, bueno, editables. En caso de que no lo hayas notado, todos los elementos que contengan la editable la clase obtiene un fondo azul al pasar el mouse para indicar esta capacidad.

Doble click para editar los contenidos. Utilice los enlaces creados dinámicamente para guardar o descartar los cambios. Puede abrir tantos campos para editar como desee sin ningún problema.

yo

  • soy Siddharth
  • me encanta trabajar con la web
  • Soy un profesional independiente
  • escribir para Net Tuts
  • se puede encontrar en www.ssiddharth.com
  • nunca te decepcionará ni te rendirá :)

Cosas que hacer esta semana

  • Obtener la aprobación del diseño de Deacon
  • Envía una factura a Albert
  • Empezar a trabajar en el proyecto de Dwight.
  • Habla con Sarah sobre nuevas ideas.
  • Revisa el sitio de Seth para ver si hay errores.
  • Reunirse con Clintson para discutir el proyecto.

Como ve, sin tener en cuenta la placa de la caldera, tenemos dos listas desordenadas. Cada li elemento tiene una clase de editable Para denotar que su contenido puede ser editado..

También hemos incluido la biblioteca jQuery y nuestro propio archivo de script.

Estilo CSS

 body font-family: "Lucida Grande", "Verdana", sans-serif; tamaño de fuente: 12px;  a color: # 000;  a: hover text-decoration: none;  p margen: 30px 0 10px 0;  h1 font-size: 30px; relleno: 0; margen: 0;  h2 font-size: 20px;  #container width: 820px; margen izquierdo: auto; margen derecho: auto; relleno: 50px 0 0 0;  .editHover background-color: # E8F3FF;  .editBox width: 326px; min-height: 20px; relleno: 10px 15px; color de fondo: #fff; frontera: 2px sólido # E8F3FF;  ul estilo de lista: ninguno;  li ancho: 330px; min-height: 20px; relleno: 10px 15px; margen: 5px;  li.noPad padding: 0; ancho: 360px;  forma ancho: 100%;  .btnSave, .btnCancel relleno: 6px 30px 6px 75px;  .block float: left; margen: 20px 0; 

Nada especial aquí. Sólo un montón de código para fines de diseño y estilo.

Tome nota especial de la editHover y noPad clases Los usaremos en un momento..

Implementación de JavaScript

Ahora que tenemos un marco sólido y un estilo básico en su lugar, podemos comenzar a codificar la funcionalidad requerida. Tenga en cuenta que hacemos uso extenso de jQuery. Específicamente necesitaremos al menos la versión 1.3 o superior. Nada menos y no funcionará..

Añadiendo Hovers

Como se señaló anteriormente, tendremos que agregar un fondo azul sutil a los objetos editables para indicar que son editables. Ya hemos creado el editHover clase para cuidar de esto.

 $ (".editable"). hover (function () $ (this) .addClass ("editHover");, function () $ (this) .removeClass ("editHover"););

Este pequeño fragmento se encarga de eso por nosotros. Usamos jQuery flotar método para agregar el editHover clase cuando el elemento se desplaza sobre él y eliminarlo cuando no lo es. Usamos esta para referirse al elemento específico que se desplaza sobre. Si hubiéramos usado .editable como selector en su lugar, cada elemento obtendrá la clase agregada. Entonces usamos esta para apuntar solo al elemento que necesitamos.

Cambiando los elementos

En primer lugar, debemos asegurarnos de que nuestro código se ejecuta cuando se hace doble clic en el elemento de destino. Así que primero conectaremos el controlador para este evento primero.

 $ (". editable"). bind ("dblclick", replaceHTML);

Adjuntamos el reemplazarHTML función a la haga doble clic evento relativo a la editable Elemento con ese forro. Ahora podemos pasar a la conmutación de los elementos..

 function replaceHTML () oldText = $ (this) .html () .replace (/ "/ g," ""); $ (este) .html ("") .html ("
Guardar cambios Descartar cambios ");

Vamos a revisar nuestro código poco a poco.

Defino la funcionalidad dentro de una función nombrada separada en lugar de una función anónima por una razón específica: usaré esta función más de una vez. A continuación, guardamos el contenido del elemento para uso futuro utilizando jQuery's html Método y reemplazo de todas las citas, ya que desordena nuestra salida en la línea.

Ahora que nuestro contenido se almacena de forma segura para su uso posterior, podemos cambiar los elementos. Primero vaciamos el li elemento enviando en una cadena vacía a la html método. A continuación, insertamos algún HTML estándar para un cuadro de entrada. Le añadimos algunas clases para fines de estilo. Más importante aún, establecemos su valor atribuir al texto original contenido por el elemento almacenado en viejoTexto. También agregamos un par de enlaces para guardar y descartar las ediciones. También les hemos agregado clases para que puedan orientarse fácilmente y para el estilo..

Como siempre, usamos esta para apuntar al elemento que desencadenó el evento.

Mantener las ediciones

 $ (". btnSave"). live ("click", function () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g , "" "); $ (this) .parent () .html (newText););

En primer lugar, permítanme presentarles jQuery vivir método. Probablemente no hayas visto esto antes, así que daré una breve introducción..

No puede conectar manejadores a eventos desencadenados por elementos que ni siquiera están presentes en el DOM cuando se cargó la página y el JavaScript. Si utiliza las funciones de enlace de eventos normales, fallará debido a la razón mencionada anteriormente. los vivir el metodo se encarga de eso.

Enlaza los controladores a los eventos, independientemente de cuándo se creó el elemento. Para más sobre esto, puedes ir a través de los documentos oficiales..

Echemos un vistazo a nuestro código ahora. Primero enlazamos el código contenido dentro de nuestra función anónima al hacer clic evento. Dentro de la función primero guardamos el texto contenido en el cuadro de entrada. Esto puede ser un poco complicado ya que el cuadro de entrada no tiene una identificación. Así que primero buscamos el elemento de formulario que resulta ser su hermano y luego lo atravesamos para encontrar el elemento de entrada. Luego copiamos su valor después de reemplazar todas las citas que puede contener.

A continuación, obtenemos el elemento padre enlaces, el li Elemento y reemplace su contenido HTML con el texto que copiamos en el paso anterior.

Este bloque podría haber sido creado fácilmente como una sola línea, pero opté por dividirlo en 2 líneas en aras de la legibilidad.

Descartando las ediciones

 $ (". btnDiscard"). live ("click", function () $ (this) .parent () .html (oldText););

Esto es tan simple como parece. Dado que el usuario no quiere mantener ninguna de las ediciones. Simplemente reemplazamos el contenido HTML del elemento principal con el texto original que habíamos copiado anteriormente al viejoTexto variable.

Con esto se hace el núcleo de nuestro trabajo. Solo necesitamos hacer un par de ediciones para asegurarnos de que las cosas no se rompan cuando el usuario hace cosas inesperadas..

Encuadernación y desenganche

Si ya probó nuestro código en este punto, probablemente terminará con este error de interrupción de la funcionalidad: cuando un usuario hace doble clic en el cuadro de entrada resultante, ahora está lleno del contenido HTML del sistema de edición. Inténtalo tú mismo. Con cada doble clic, el valor del cuadro de entrada se refleja al agregarle otro grupo de texto. Este problema probablemente será mucho peor si ha elegido hacer clic como evento desencadenante.

Para corregir esto, debemos desenlazar el controlador de eventos para ese elemento específico solo y volver a vincularlos tan pronto como el usuario haga clic en guardar o descartar. Vamos a implementar eso ahora.

Nuestros bloques de código anteriores ahora deben ser editados para:

 function replaceHTML () // Code $ (this) .html ("") // Código de inserción de formulario anterior .unbind ('dblclick', replaceHTML); 

Desconectamos el controlador del elemento que desencadenó el evento. El resto de los elementos con el editable La clase todavía tiene sus controladores intactos y responderá a los eventos..

 $ (". btnSave"). live ("click", function () // Código anterior $ (this) .parent () .html (newText) .bind ("dblclick", replaceHTML););
 $ (". btnDiscard"). live ("click", function () $ (this) .parent () .html (oldText) .bind ("dblclick", replaceHTML););

A continuación, volvemos a adjuntar esos controladores a pesar de que el usuario elija editarlos o no. Si no los volvemos a adjuntar, los campos solo se pueden editar una vez. La segunda vez que se hace doble clic, los controladores ya no están vinculados a los eventos. Rectificamos esto conectando los controladores a los eventos.

Unos cuantos retoques

Este último bit de código es simplemente para mejorar la apariencia de nuestro efecto. Si te has dado cuenta, la li tiene un poco de relleno en su lugar para hacer que el texto se vea mejor. Pero cuando el texto se elimina y se reemplaza por un cuadro de texto, el resultado es feo y rompe el efecto. Queremos que el cuadro de texto ocupe exactamente el mismo espacio que el texto original. Con esto en mente, añadimos un noPad clase al elemento cuando se ha hecho doble clic y se ha eliminado de nuevo cuando el usuario guarda o descarta la edición.

 función replaceHTML () // Code $ (this) .addClass ("noPad") .html ("") // Código anterior

Desconectamos el controlador del elemento que desencadenó el evento. El resto de los elementos con el editable La clase todavía tiene sus manejadores intactos y responderá a los eventos..

 $ (". btnSave"). live ("click", function () // Código anterior $ (this) .parent () .removeClass ("noPad") // Código anterior);
 $ (". btnDiscard"). live ("click", function () $ (this) .parent () .removeClass ("noPad") // Código anterior);

El Código Completo

Aquí es cómo se ve el código completo:

 $ (document) .ready (function () var oldText, newText; $ (". editable"). hover (function () $ (this) .addClass ("editHover");, function () $ ( this) .removeClass ("editHover");); $ (". editable"). bind ("dblclick", replaceHTML); $ (". btnSave"). live ("click", function () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g," ""); $ (this) .parent () .html (newText). removeClass ("noPad") .bind ("dblclick", replaceHTML);); $ (". btnDiscard"). live ("click", function () $ (this) .parent () .html (oldText) .removeClass ("noPad") .bind ("dblclick", replaceHTML);); function replaceHTML () oldText = $ (this) .html () .replace (/ "/ g," ""); $ ( this) .addClass ("noPad") .html ("") .html ("
Guarde los cambios .unbind ('dblclick', replaceHTML); );

No está mal. Cincuenta líneas impares para agregar alguna funcionalidad nueva y elegante.

Yendo un paso más allá: el backend

Con el fin de no hacerlo demasiado largo, me he limitado a crear solo la funcionalidad del lado del cliente. Si desea implementar esta funcionalidad dentro de sus propios proyectos, se asume implícitamente que necesitará un sistema de back-end para guardar estos cambios y, lo que es más importante, necesitará una solicitud AJAX para realizar esta llamada de forma asíncrona..

Agregar esta funcionalidad debería ser muy fácil, pero tome nota de esto. El código anterior fue creado solo para ilustrar este patrón y no para uso de producción. Así que me he abstenido de agregar atributos de ID adicionales a elementos y nombres de atributos a cuadros de texto. En su código de producción, agregue todos ellos para que el atributo de nombre del cuadro de texto se pueda configurar de manera significativa y de tal manera que el back-end pueda reconocer qué datos deben actualizarse.

Para agregar una solicitud AJAX, nuestro controlador de guardado debería actualizarse para que:

 $ (". btnSave"). live ("click", function () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g , "" "); $ .ajax (type:" POST ", url:" handler.php ", data: newText, success: function (msg) // Algún código aquí para reflejar una edición exitosa;) ; $ (this) .parent () .html (newText) .removeClass ("noPad") .bind ("dblclick", replaceHTML););

Recuerde, para que el back-end tenga algún sentido de lo que le está enviando, necesita algunos datos adicionales junto con el texto actualizado para que la aplicación sepa qué datos editar. Fácilmente puede enviar más de una pieza de datos al script si necesita.

Conclusión

Y ahí lo tienes; Cómo agregar una funcionalidad amigable para el usuario a tus proyectos. Esperemos que este tutorial te haya resultado interesante y te haya sido útil. Siéntase libre de reutilizar este código en cualquier otra parte de sus proyectos y toque aquí si tiene dificultades..

Preguntas? Cosas bonitas que decir? Criticas? Pulsa la sección de comentarios y déjame un comentario. Feliz codificacion!

  • Síganos en Twitter o suscríbase a Nettuts + RSS Feed para obtener más artículos y artículos de desarrollo web diarios..