Quiero insertar caracteres TAB dentro de una TEXTAREA, así:

<textarea>{KEYPRESS-INSERTS-TAB-HERE}Hello World</textarea>

Puedo insertar antes / después del texto TEXTAREA existente, y puedo insertar / reemplazar todo el texto en TEXTAREA, pero aún no he podido insertar dentro de el texto TEXTAREA existente (con el cursor) de una manera simple.

$('textarea:input').live('keypress', function(e) {
    if (e.keyCode == 9) {
        e.preventDefault();

        // Press TAB to append a string (keeps the original TEXTAREA text).
        $(this).append("TAB TAB TAB AFTER TEXTAREA TEXT");

        // Press TAB to append a string (keeps the original TEXTAREA text).
        $(this).focus().prepend("TAB TAB TAB BEFORE TEXTAREA TEXT");

        // Press TAB to replace a all text inside TEXTAREA.
        $(this).val("INSERT INTO TEXTAREA / REPLACE EXISTING TEXT");

    }
});

Hay un complemento "pestañas en textarea" para jQuery ("Tabby"), pero es 254 líneas de código: esperaba solo unas pocas líneas de código.

Algunos enlaces que estudié: (nuevamente, preferiría menos líneas de código).

http://www.dynamicdrive.com/forums/showthread.php?t=34452
http://www.webdeveloper.com/forum/showthread.php?t=32317
http://pallieter.org/Projects/insertTab/

Por favor avise. Gracias.

7
Kristoffer Bohmann 15 nov. 2009 a las 23:59

4 respuestas

La mejor respuesta

Estaba creando un IDE simple con AJAX para mí, así puedo probar rápidamente fragmentos de PHP.

Recuerdo tropezar con el mismo problema, así es como lo resolví:

$('#input').keypress(function (e) {
    if (e.keyCode == 9) {
        var myValue = "\t";
        var startPos = this.selectionStart;
        var endPos = this.selectionEnd;
        var scrollTop = this.scrollTop;
        this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos,this.value.length);
        this.focus();
        this.selectionStart = startPos + myValue.length;
        this.selectionEnd = startPos + myValue.length;
        this.scrollTop = scrollTop;

        e.preventDefault();
    }
});

#input es la ID del área de texto.

El código no es completamente mío, lo encontré en Google en alguna parte.

Solo lo he probado en FF 3.5 e IE7. Lamentablemente, no funciona en IE7.

13
Waleed Amjad 15 nov. 2009 a las 21:24

Por cierto, vea también:
http://aspalliance.com/346_Tabbing_in_the_TextArea

0
Kristoffer Bohmann 16 nov. 2009 a las 05:07

Sí, lidiar con las selecciones de campo de entrada en los diferentes navegadores es una molestia, especialmente porque en IE hay algunos métodos que parecen como deberían funcionar, pero en realidad no lo hacen. (Notablemente, combinando usando setEndPoint y luego midiendo length, que se ve bien hasta que la selección comienza o termina en nuevas líneas).

Aquí hay un par de funciones de utilidad que uso para manejar las selecciones de entrada. Devuelve el valor de la entrada dividida en bits que están antes, dentro y después de la selección (con la selección contando como una cadena vacía en la posición del foco de entrada si no es una selección). Esto hace que sea muy sencillo reemplazar e insertar contenido en el punto que desee, mientras se ocupa del problema de IE CRLF.

(Puede haber un jQuery que haga algo como esto, pero todavía tengo que encontrar uno).

// getPartitionedValue: for an input/textarea, return the value text, split into
// an array of [before-selection, selection, after-selection] strings.
//
function getPartitionedValue(input) {
    var value= input.value;
    var start= input.value.length;
    var end= start;
    if (input.selectionStart!==undefined) {
        start= input.selectionStart;
        end= input.selectionEnd;
    } else if (document.selection!==undefined) {
        value= value.split('\r').join('');
        start=end= value.length;
        var range= document.selection.createRange();
        if (range.parentElement()===input) {
            var start= -range.moveStart('character', -10000000);
            var end= -range.moveEnd('character', -10000000);
            range.moveToElementText(input);
            var error= -range.moveStart('character', -10000000);
            start-= error;
            end-= error;
        }
    }
    return [
        value.substring(0, start),
        value.substring(start, end),
        value.substring(end)
    ];
}

// setPartitionedValue: set the value text and selected region in an input/
// textarea.
//
function setPartitionedValue(input, value) {
    var oldtop= input.scrollTop!==undefined? input.scrollTop : null;
    input.value= value.join('');
    input.focus();
    var start= value[0].length;
    var end= value[0].length+value[1].length;
    if (input.selectionStart!==undefined) {
        input.selectionStart= start;
        input.selectionEnd= end;
        if (oldtop!==null)
            input.scrollTop= oldtop;
    }
    else if (document.selection!==undefined) {
        var range= input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', end);
        range.moveStart('character', start);
        range.select();
    }
}
1
bobince 15 nov. 2009 a las 22:28

Desafortunadamente, manipular el texto dentro de los elementos del área de texto no es tan simple como uno podría esperar. La razón por la que Tabby es más grande que esos fragmentos simples es porque funciona mejor. Tiene una mejor compatibilidad entre navegadores y maneja cosas como selecciones de tabulación.

Cuando se minimiza, solo se trata de 5k. Sugeriría usarlo. De todos modos, tendrá que descubrir y resolver los mismos casos límite usted mismo, o tal vez ni siquiera sepa sobre ellos si los usuarios no los denuncian.

5
Dave Ward 15 nov. 2009 a las 21:15