Estoy creando una nueva forma de editar las paginas web que contiene algún tipo de CMS. Como ustedes saben, ese tipo de aplicaciones te permiten editar los textos una vez han sido creados y publicados, pero yo algunas veces me encuentro en que cuando reviso el post, me doy cuenta que me falta un acento o se me fue una letra de mas o cosas así. Entonces tengo que darle al botón editar, esperar que se cargue la pagina en la que se puede editar el contenido, editar el contenido, darle a salvar y volver a ver el post publicado. Esto es muy tedioso sobre todo cuando lo único que quiero es cambiar una letra.
Para solucionar este "problema" pensé en un sistema que permitiera seleccionar la parte del texto que se quiere edita, este automáticamente se convierte en un input tipo text listo para ser editado sin tener que dar todo el viaje redondo que expliqué anteriormente. Hasta ahi todo genial. El problema esta en que para que el texto sea enviado al servidor y el cambio reflejado en la pagina, esto es, mostrar el texto tal cual sin la caja de texto, estoy usando dos eventos. Uno es el onblur de la caja de texto, así cuando la caja pierde el foco el texto editado es impreso en la pantalla. Dos, el evento onmouseup de mi elemento en el que tengo el texto. Este segundo hace dos cosas, primero cuando seleccionas un texto por primera vez convierte dicho texto en caja de texto para ser editado. Cuando presionas por segunda vez imprime el texto.
La cosa funciona bien cuando el onblur es causado por el usuario presionando TAB o por un click fuera del elemento en el que tengo el texto. Sin embargo, cuando el onblur es causado por un click dentro del elemento en el que tengo el texto, se activan los dos evento a la vez. Primero se activa el evento onblur de la caja de texto, lo cual imprime el texto como normalmente lo haría. Segundo, se activa el evento onmouseup de mi elemento en el que tengo el texto, lo cual me crea una nueva caja de texto tal como si se hubiera seleccionado otra parte de texto y eso no me gusta. Si quieren ver lo que les digo pueden probar este codigo:
Código HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>seleccion</title> <script type="text/javascript"> var editar = true; function sel(){ if(editar == true){ var texto = document.getElementById('seleccion'); var inicio = window.getSelection().anchorOffset; var Final = window.getSelection().focusOffset; var textoIni = texto.innerHTML; textoAnterior = textoIni.substr(0, inicio); textoPosterior = textoIni.substr(Final); var cajaValue = window.getSelection().toString(); var textoFn = textoAnterior + "<input type='text' id='editando' value='" + cajaValue + "' size='" + cajaValue.length + "' />" + textoPosterior; texto.innerHTML = textoFn; document.getElementById('editando').focus(); document.getElementById('editando').select(); document.getElementById('editando').onblur = imprimeTexto; editar = false; }else if(editar == false){ imprimeTexto(); } } function imprimeTexto(){ document.getElementById('seleccion').innerHTML = textoAnterior + document.getElementById('editando').value + textoPosterior; editar = true; } </script> </head> <body> <div id="seleccion" onmouseup="sel();"> texto que podra o no ser seleccionado. Al seleccionar devera ser convertido en una caja de texto para que sea editado. </div> </body> </html>
Yo lo eh solucionado de esta manera:
1.- En cuanto el texto es impreso, elimino la función asignada al evento onmouseup de mi elemento texto de tal modo que no se ejecute y no me abra otra caja de texto.
2.- Uso setTimeout para volver a asignar la función al evento onmouseup cuando creo que es seguro de modo que cuando el texto sea seleccionado nuevamente me cree la caja de texto.
Un poco difícil de explicar. Acá mi solución:
Código HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>seleccion</title> <script type="text/javascript"> var editar = true; function sel(){ if(editar == true){ var texto = document.getElementById('seleccion'); var inicio = window.getSelection().anchorOffset; var Final = window.getSelection().focusOffset; var textoIni = texto.innerHTML; textoAnterior = textoIni.substr(0, inicio); textoPosterior = textoIni.substr(Final); var cajaValue = window.getSelection().toString(); var textoFn = textoAnterior + "<input type='text' id='editando' value='" + cajaValue + "' size='" + cajaValue.length + "' />" + textoPosterior; texto.innerHTML = textoFn; document.getElementById('editando').focus(); document.getElementById('editando').select(); document.getElementById('editando').onblur = imprimeTexto; editar = false; } } function imprimeTexto(){ document.getElementById('seleccion').onmouseup=""; setTimeout("document.getElementById('seleccion').onmouseup=sel",100); document.getElementById('seleccion').innerHTML = textoAnterior + document.getElementById('editando').value + textoPosterior; editar = true; } </script> </head> <body> <div id="seleccion" onmouseup="sel();"> texto que podra o no ser seleccionado. Al seleccionar devera ser convertido en una caja de texto para que sea editado. </div> </body> </html>
La pregunta es. Es esta la mejor forma de evitar el doble evento o hay una manera mejor de hacerlo?