2011-03-26 16 views
19

Acabo de encontrar una situación en la que sería una solución elegante tener solo partes del área de texto (previamente cargadas con texto) editables, mientras que otras partes no ("atenuadas" ", por así decirlo).¿Hay alguna manera de hacer que un área de texto sea parcialmente editable? (solo editable partes del texto)

¿Esto es posible usando javascript en general?

Yo estaría usando jQuery.

+0

existirá el contenido no editable en porciones separadas del texto, o que será fijado (ex: al principio o al final)? –

+0

@Mohammed La solución ideal dada mi situación específica sería tener lotes de texto editable. Esas partes serían identificables al estar encerradas entre algunos marcadores (como @ {} por ejemplo) –

+1

Hola Kensai, ¿Terminaste implementando una solución? Me gustaría saber de eso porque estoy tratando de hacer esto ahora. Gracias! – user418775

Respuesta

8

usted puede hacer esto (sólo una idea esbozado, sin código):

idear una expresión regular que coincide con la totalidad de su texto. Use cadenas fijas para las partes no modificables, y use [\s\S]*? para las partes modificables. Use ^ y $ para anclar su expresión regular.

/^This is fixed text\. Now something editable:[\s\S]*?Now fixed again\.$/ 

Ahora reaccionar al evento keyup, y probablemente otros eventos, así (como paste).

Con cada evento relevante, compruebe si la expresión regular aún coincide.

Si no lo hace, cancele el evento.

Efectivamente, esto debería detener las modificaciones a las partes que son literales en la expresión regular y, por lo tanto, hacer que ciertas partes de su texto sean de solo lectura.

No olvide probar la cadena en el servidor también después de la publicación del formulario: nunca confíe en que el cliente no puede enviar valores no válidos.


EDITAR

Se puede utilizar una función de cotización de expresiones regulares para crear dinámicamente a partir de cadenas de expresiones regulares que, esto debe ahorrar mucho la molestia.

function regexQuote(s) { return s.replace(/[\[\]^$*+?{}.|\\]/g, "\\$&") } 

uso

var re = new Regex(
    "^" + 
    [regexQuote(fixedPart1), regexQuote(fixedPart2)].join("[\\s\\S].*?") 
    + "$" 
); 
+3

Aquí hay una implementación usando el evento "de entrada" (que por desgracia no está completamente compatible con IE9): https://jsfiddle.net/un6c950h/. El uso de eventos "keyup" y "paste" introduce el comportamiento de jumpy donde el valor cambia y luego se restaura: https://jsfiddle.net/un6c950h/2/ – Peter

1

Idea interesante, pero lamentablemente, el texto dentro del área de texto debe tratarse de manera uniforme, es decir, no puede deshabilitar una subsección del contenido del área de texto.

Tiene opciones, sin embargo. Si puede identificar el texto que debe deshabilitarse, puede agregarlo como un elemento DOM (es decir, un div) y luego colocarlo de una manera que implique que está dentro del área de texto.

Puede implicar que este div está dentro del área de texto al hacer que el área de texto sea grande y usar la posición: estilos relativos/absolutos para mover el div sobre el área de texto. O bien, puede quitar el borde en el área de texto y colocarlo en un contenedor que también contenga el texto div w/"disabled".

8

Si está utilizando un elemento de texto plano simple, no podrá ajustar el contenido requerido (en función de si ese contenido es editable o no). En el mejor de los casos, podría verificar si el contenido que su usuario intenta cambiar está en la lista negra o en la lista blanca y luego detener la edición o no en consecuencia. También puede proporcionar algunos comentarios visuales, como un mensaje de advertencia que dice "no se puede hacer eso".

Mi recomendación sería aprovechar el atributo contenteditable, lo que puede llevar un poco más de tiempo en darle estilo, pero le permitirá una mayor flexibilidad a largo plazo.

Podrías estilizar un elemento div para que se parezca mucho al área de texto requerida, y luego usar tramos editables para establecer si un determinado bloque de texto se puede editar o no. Luego puede usar los comandos de JavaScript (consulte el enlace anterior) o use un botón "guardar" para recuperar este contenido, configúrelo como el valor de su área de texto real (que podría haber ocultado) y vuelva a publicar su página como siempre.

Utilice el siguiente código como un ejemplo aproximado.

<div id="editable-content"> 
    <span id="block1" class="editable" contenteditable="true">This is some editable content which will </span> 
    <span id="block2" class="non-editable">quickly be followed by some non-editable content</span> 
</div> 
<div style="display: none;"> 
    <textarea id="PostedContent"></textarea> 
</div> 
<div> 
    <input id="save-page" type="submit" value="Save Page" /> 
</div> 

<script type="text/javascript"> 
    $(function() { 
     $('#save-page').click(function() { 
      $('#PostedContent').val($('#editable-content').text()); 
     }); 
    }); 
</script> 
+1

+1 este es un buen enfoque. Sin embargo, dado que la publicación del formulario depende completamente de JavaScript, recomendaría establecer 'contentable' a través de JavaScript también. Además, recomendaría que aparezcan cuadros de mensajes. Destellar el color de fondo (o algo así) es mucho menos intrusivo. – Tomalak

+1

Esto es bueno pero tiene un comportamiento extraño en IE9 en lo que respecta a escribir algo y luego eliminarlo (a veces el siguiente texto se remonta y a veces permanece en su lugar, dejando este incómodo espacio en blanco) –

+0

Ambos muy buenos puntos . –

1

me gustaría sugerir, en lugar de tratar de romper el contenido de un input en sub-cadenas de contenido editable/no editable, se utiliza el atributo contentEditable de un elemento HTML, JavaScript y el uso de pasar por valor editado en un input oculto en otra parte de la página.

2

Bueno, usted podría hacer algo como esto. Este código es muy ineficiente, solo estoy tratando de delinear el concepto.

JS:

$(function() { 
      var tb = $("#t").get(0); 
      $("#t").keydown(function (event) { 
       var start = tb.selectionStart; 
       var end = tb.selectionEnd; 
       var reg = new RegExp("(@{.+?})", "g"); 
       var amatch = null; 
       while ((amatch = reg.exec(tb.value)) != null) { 
        var thisMatchStart = amatch.index; 
        var thisMatchEnd = amatch.index + amatch[0].length; 
        if (start <= thisMatchStart && end > thisMatchStart) { 
         event.preventDefault(); 
         return false; 
        } 
        else if (start > thisMatchStart && start < thisMatchEnd) { 
         event.preventDefault(); 
         return false; 
        } 
       } 
      }); 
     }); 

HTML

<textarea id="t" rows=5 cols="80">Hello this is a test @{stuff} 

     this part is editable @{other stuff}  

    </textarea> 

Esta utiliza su idea de "marcadores". La idea general es decir, ¿está el rango de texto que el usuario intenta editar dentro de uno de nuestros marcadores? Obviamente, usar una expresión regular cada vez que se presiona una tecla no es la mejor manera de determinar esto, no estoy ignorando las teclas de flechas, etc., pero esto te da una idea general.

0

En un elemento padre, se puede establecer la frontera 1px gris sólido y luego dentro de esto, poner el

1) área de texto

(modificar el css para no tener frontera) 2) etiqueta (sin borde, así)

En este caso, se verá como si los dos textos dentro de 1) y 2) están juntos ya que están colocados en una caja. 1) Es editable, mientras que el otro está en gris.

0

que sugeriría dos áreas de texto uno de sólo lectura y otro editable, la superposición de lo que parece que su único

Cuestiones relacionadas