HTML 5 Content Editable

Uno de los mayores cambios entre las especificaciones anteriores de HTML y su versión 5 es que en esta última todo puede ser editable. Estábamos acostumbrados a utilizar cierto tipos de controles para aquella información que era susceptible al cambio como los inputs, combos, etc. Para aquellos elementos que usualmente no son editables, basta con asignar el atributo contenteditable=”true” y, simplemente con pulsar sobre el mismo, seremos capaces de modificar su contenido:

Prueba a cambiar este texto 🙂

Persistiendo los cambios

Al no ser elementos inicialmente editables, aunque sean incluidos dentro de un formulario y les asignemos el atributo name, su información no queda incluida en la petición al servidor.
Para detectar los cambios ocurridos, podemos hacer uso de los eventos input y blur. Personalmente prefiero utilizar blur, ya que me indica los cambios finales una vez que el elemento haya perdido el foco, pero pueden existir escenarios en los que input, evento también nuevo en HTML 5 el cual es lanzado cuando un elemento es modificado a través de la interfaz de usuario, pueda ser igual de útil.

En ambos casos, basta con capturar el evento que más se adapte a nuestras necesidades y realizar la petición con los cambios del elemento:

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
<div id="myText" contenteditable="true">
    @ViewBag.Message
</div>

@section scripts{
    <script>
        window.onload = function () {

            myText.addEventListener("blur", function () {
                $.ajax({
                    url: '/Home/UpdateMessage',
                    type: 'POST',
                    data: { message: this.innerText }
                }).then(function (data) {
                    alert(data.message);
                });

            });
        };
    </script>
}

En este ejemplo he utilizado ASP.NET MVC, donde almaceno en ViewBag.Message el contenido del div que es editable, con el fin de simular la persistencia. En la sección scripts capturo el evento blur donde directamente hago una petición AJAX con el innerText del elemento.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace ContentEditable.Controllers
{
    public class HomeController : Controller
    {
        static string _message = "Hello World";
        //
        // GET: /Home/
        public ActionResult Index()
        {
            ViewBag.Message = _message;
            return View();
        }

        [HttpPost]
        public JsonResult UpdateMessage(string message)
        {
            _message = message;

            return Json(new
            {
                message = "Message updated: " + _message
            });

        }
    }
}

Otra opción, si queremos utilizar un formulario, es asignar el valor de los elementos editables a un input de tipo hidden para que la información navegue con el resto del contenido.

Espero que haya sido de utilidad.

Can I Use contenteditable attribute?

¡Saludos!