Tengo un simple html textarea de mi lado. En este momento, si hace clic en la pestaña, pasará al siguiente campo. Me gustaría hacer que el botón de tabulación sangrara unos espacios en su lugar. ¿Cómo puedo hacer esto? Gracias.
Tengo un simple html textarea de mi lado. En este momento, si hace clic en la pestaña, pasará al siguiente campo. Me gustaría hacer que el botón de tabulación sangrara unos espacios en su lugar. ¿Cómo puedo hacer esto? Gracias.
Respuestas:
Tomando mucho de otras respuestas para preguntas similares (publicadas a continuación) ...
$(document).delegate('#textbox', 'keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
// put caret at right position again
this.selectionStart =
this.selectionEnd = start + 1;
}
});
jQuery: cómo capturar la pulsación de tecla TAB dentro de un cuadro de texto
var textareas = document.getElementsByTagName('textarea');
var count = textareas.length;
for(var i=0;i<count;i++){
textareas[i].onkeydown = function(e){
if(e.keyCode==9 || e.which==9){
e.preventDefault();
var s = this.selectionStart;
this.value = this.value.substring(0,this.selectionStart) + "\t" + this.value.substring(this.selectionEnd);
this.selectionEnd = s+1;
}
}
}
Esta solución no requiere jQuery y habilitará la funcionalidad de pestañas en todas las áreas de texto de una página.
this.selectionEnd = s+1;
con this.selectionEnd = s + "\t".length;
. Sería más limpio usar una variable o parámetro de función y almacenar los caracteres de sangría allí. Pero ahora sabe qué reemplazar: +1
define la cantidad de caracteres que se mueve el cursor.
KeyboardEvent.keyCode
y KeyboardEvent.which
son propiedades en desuso. Usar en su KeyboardEvent.key
lugar.
Como otros han escrito, puede usar JavaScript para capturar el evento, evitar la acción predeterminada (para que el cursor no cambie el foco) e insertar un carácter de tabulación.
Pero , deshabilitar el comportamiento predeterminado hace que sea imposible mover el foco fuera del área de texto sin usar un mouse. Los usuarios ciegos interactúan con páginas web utilizando el teclado y nada más: no pueden ver el puntero del mouse para hacer nada útil con él, por lo que es teclado o nada. La tecla de tabulación es la forma principal de navegar por el documento, y especialmente los formularios. Anular el comportamiento predeterminado de la tecla de tabulación hará que sea imposible para los usuarios ciegos mover el foco al siguiente elemento del formulario.
Por lo tanto, si está escribiendo un sitio web para una audiencia amplia, recomendaría no hacerlo sin una razón convincente , y ofrecer algún tipo de alternativa para usuarios ciegos que no los atrape en el área de texto.
Para lo que vale, aquí está mi línea, por lo que todos han estado hablando en este hilo:
<textarea onkeydown="if(event.keyCode===9){var v=this.value,s=this.selectionStart,e=this.selectionEnd;this.value=v.substring(0, s)+'\t'+v.substring(e);this.selectionStart=this.selectionEnd=s+1;return false;}">
</textarea>
Probado en las últimas ediciones de Chrome, Firefox, Internet Explorer y Edge.
if(event.shiftKey){if(v.substring(s-1,s)==='\t'){this.value=v.substring(0,s-1)+v.substring(e);this.selectionStart=this.selectionEnd=s-1;}}
Aquí está mi versión de esto, soporta:
$(function() {
var enabled = true;
$("textarea.tabSupport").keydown(function(e) {
// Escape key toggles tab on/off
if (e.keyCode==27)
{
enabled = !enabled;
return false;
}
// Enter Key?
if (e.keyCode === 13 && enabled)
{
// selection?
if (this.selectionStart == this.selectionEnd)
{
// find start of the current line
var sel = this.selectionStart;
var text = $(this).val();
while (sel > 0 && text[sel-1] != '\n')
sel--;
var lineStart = sel;
while (text[sel] == ' ' || text[sel]=='\t')
sel++;
if (sel > lineStart)
{
// Insert carriage return and indented text
document.execCommand('insertText', false, "\n" + text.substr(lineStart, sel-lineStart));
// Scroll caret visible
this.blur();
this.focus();
return false;
}
}
}
// Tab key?
if(e.keyCode === 9 && enabled)
{
// selection?
if (this.selectionStart == this.selectionEnd)
{
// These single character operations are undoable
if (!e.shiftKey)
{
document.execCommand('insertText', false, "\t");
}
else
{
var text = this.value;
if (this.selectionStart > 0 && text[this.selectionStart-1]=='\t')
{
document.execCommand('delete');
}
}
}
else
{
// Block indent/unindent trashes undo stack.
// Select whole lines
var selStart = this.selectionStart;
var selEnd = this.selectionEnd;
var text = $(this).val();
while (selStart > 0 && text[selStart-1] != '\n')
selStart--;
while (selEnd > 0 && text[selEnd-1]!='\n' && selEnd < text.length)
selEnd++;
// Get selected text
var lines = text.substr(selStart, selEnd - selStart).split('\n');
// Insert tabs
for (var i=0; i<lines.length; i++)
{
// Don't indent last line if cursor at start of line
if (i==lines.length-1 && lines[i].length==0)
continue;
// Tab or Shift+Tab?
if (e.shiftKey)
{
if (lines[i].startsWith('\t'))
lines[i] = lines[i].substr(1);
else if (lines[i].startsWith(" "))
lines[i] = lines[i].substr(4);
}
else
lines[i] = "\t" + lines[i];
}
lines = lines.join('\n');
// Update the text area
this.value = text.substr(0, selStart) + lines + text.substr(selEnd);
this.selectionStart = selStart;
this.selectionEnd = selStart + lines.length;
}
return false;
}
enabled = true;
return true;
});
});
textarea
{
width: 100%;
height: 100px;
tab-size: 4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea class="tabSupport">if (something)
{
// This textarea has "tabSupport" CSS style
// Try using tab key
// Try selecting multiple lines and using tab and shift+tab
// Try pressing enter at end of this line for auto indent
// Use Escape key to toggle tab support on/off
// eg: press Escape then Tab to go to next field
}
</textarea>
<textarea>This text area doesn't have tabSupport class so disabled here</textarea>
Manera moderna de que ambos son sencillos y no pierden la capacidad de deshacer (Ctrl + Z) los últimos cambios.
$('#your-textarea').keydown(function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode === $.ui.keyCode.TAB) {
e.preventDefault();
const TAB_SIZE = 4;
// The one-liner that does the magic
document.execCommand('insertText', false, ' '.repeat(TAB_SIZE));
}
});
Más sobre execCommand
:
Como se señaló en el comentario (y aunque esta vez fue una solución "moderna" ), la característica se ha vuelto obsoleta. Citando los documentos:
Esta característica es obsoleta. Aunque todavía puede funcionar en algunos navegadores, se desaconseja su uso, ya que podría eliminarse en cualquier momento. Intenta evitar usarlo.
indent-textarea
con una solución de navegador cruzado que use este método + una alternativa en Firefox.
document.execCommand
solo se habilita después de la configuración document.designMode = "on";
. Puedo obtener texto para escribir en elementos que tienen .contentEditable = 'true'
. Sin embargo, cuando intento lograr esto en un área de texto, el textNode insertado se coloca justo antes del área de texto dentro del documento (en lugar de en el área de texto). Intenta ayudar a Mozilla a resolver esto aquí .
execCommand
): 'Esta característica está obsoleta. Aunque todavía puede funcionar en algunos navegadores, se desaconseja su uso, ya que podría eliminarse en cualquier momento. Intenta evitar usarlo.
No estaba llegando a ninguna parte rápidamente tratando de usar la respuesta de @ kasdega en un entorno AngularJS, nada de lo que intenté parecía capaz de hacer que Angular actuara sobre el cambio. Entonces, en caso de que sea útil para los transeúntes, aquí hay una reescritura del código de @ kasdega, estilo AngularJS, que funcionó para mí:
app.directive('ngAllowTab', function () {
return function (scope, element, attrs) {
element.bind('keydown', function (event) {
if (event.which == 9) {
event.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
element.val(element.val().substring(0, start)
+ '\t' + element.val().substring(end));
this.selectionStart = this.selectionEnd = start + 1;
element.triggerHandler('change');
}
});
};
});
y:
<textarea ng-model="mytext" ng-allow-tab></textarea>
element.triggerHandler('change');
, de lo contrario el modelo no se actualizará (por lo element.triggerHandler('change');
que pienso.
Tienes que escribir el código JS para atrapar la pulsación de la tecla TAB e insertar un montón de espacios. Algo similar a lo que hace JSFiddle.
Compruebe el violín jquery :
HTML :
<textarea id="mybox">this is a test</textarea>
JavaScript :
$('#mybox').live('keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
alert('tab pressed');
}
});
event.preventDefault();
e.keyCode || e.which
.
Script de indentación de varias líneas basado en la solución @kasdega.
$('textarea').on('keydown', function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode === 9) {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
var val = this.value;
var selected = val.substring(start, end);
var re = /^/gm;
var count = selected.match(re).length;
this.value = val.substring(0, start) + selected.replace(re, '\t') + val.substring(end);
this.selectionStart = start;
this.selectionEnd = end + count;
}
});
start === end
.
Esta solución permite tabular en una selección completa, como su editor de código típico, y también desmarcar esa selección. Sin embargo, no he descubierto cómo implementar shift-tab cuando no hay selección.
$('#txtInput').on('keydown', function(ev) {
var keyCode = ev.keyCode || ev.which;
if (keyCode == 9) {
ev.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
var val = this.value;
var selected = val.substring(start, end);
var re, count;
if(ev.shiftKey) {
re = /^\t/gm;
count = -selected.match(re).length;
this.value = val.substring(0, start) + selected.replace(re, '') + val.substring(end);
// todo: add support for shift-tabbing without a selection
} else {
re = /^/gm;
count = selected.match(re).length;
this.value = val.substring(0, start) + selected.replace(re, '\t') + val.substring(end);
}
if(start === end) {
this.selectionStart = end + count;
} else {
this.selectionStart = start;
}
this.selectionEnd = end + count;
}
});
#txtInput {
font-family: monospace;
width: 100%;
box-sizing: border-box;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="txtInput">
$(document).ready(function(){
$("#msgid").html("This is Hello World by JQuery");
});
</textarea>
if (selected.length > 0) {...}
Fiddle simple : jsfiddle.net/jwfkbjkr
Según todo lo que la gente tenía que decir aquí sobre las respuestas, es solo una combinación de keydown (no keyup) + preventDefault () + insertar un carácter de tabulación en el cursor. Algo como:
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
insertAtCaret('txt', '\t')
}
La respuesta anterior tenía un jsfiddle que funcionaba pero usaba una alerta () en el keydown. Si elimina esta alerta, entonces no funcionó. Acabo de agregar una función para insertar una pestaña en la posición actual del cursor en el área de texto.
Aquí está trabajando jsfiddle para lo mismo: http://jsfiddle.net/nsHGZ/
Veo que este tema no está resuelto. Codifiqué esto y está funcionando muy bien. Inserta una tabulación en el índice del cursor. Sin usar jquery
<textarea id="myArea"></textarea>
<script>
document.getElementById("myArea").addEventListener("keydown",function(event){
if(event.code==="Tab"){
var cIndex=this.selectionStart;
this.value=[this.value.slice(0,cIndex),//Slice at cursor index
"\t", //Add Tab
this.value.slice(cIndex)].join('');//Join with the end
event.stopPropagation();
event.preventDefault(); //Don't quit the area
this.selectionStart=cIndex+1;
this.selectionEnd=cIndex+1; //Keep the cursor in the right index
}
});
</script>
Hice uno al que puede acceder con cualquier elemento de área de texto que desee:
function textControl (element, event)
{
if(event.keyCode==9 || event.which==9)
{
event.preventDefault();
var s = element.selectionStart;
element.value = element.value.substring(0,element.selectionStart) + "\t" + element.value.substring(element.selectionEnd);
element.selectionEnd = s+1;
}
}
Y el elemento se vería así:
<textarea onkeydown="textControl(this,event)"></textarea>
La forma más simple que encontré para hacer eso en los navegadores modernos con JavaScript vainilla es:
<textarea name="codebox"></textarea>
<script>
const codebox = document.querySelector("[name=codebox]")
codebox.addEventListener("keydown", (e) => {
let { keyCode } = e;
let { value, selectionStart, selectionEnd } = codebox;
if (keyCode === 9) { // TAB = 9
e.preventDefault();
codebox.value = value.slice(0, selectionStart) + "\t" + value.slice(selectionEnd);
codebox.setSelectionRange(selectionStart+2, selectionStart+2)
}
});
</script>
Tenga en cuenta que utilicé muchas funciones de ES6 en este fragmento por simplicidad, probablemente querrá volver a compilarlo (con Babel o TypeScript) antes de implementarlo.
Lo anterior responde a todo borrar historial de deshacer. Para cualquiera que busque una solución que no haga eso, pasé la última hora codificando lo siguiente para Chrome:
jQuery.fn.enableTabs = function(TAB_TEXT){
// options
if(!TAB_TEXT)TAB_TEXT = '\t';
// text input event for character insertion
function insertText(el, text){
var te = document.createEvent('TextEvent');
te.initTextEvent('textInput', true, true, null, text, 9, "en-US");
el.dispatchEvent(te);
}
// catch tab and filter selection
jQuery(this).keydown(function(e){
if((e.which || e.keyCode)!=9)return true;
e.preventDefault();
var contents = this.value,
sel_start = this.selectionStart,
sel_end = this.selectionEnd,
sel_contents_before = contents.substring(0, sel_start),
first_line_start_search = sel_contents_before.lastIndexOf('\n'),
first_line_start = first_line_start_search==-1 ? 0 : first_line_start_search+1,
tab_sel_contents = contents.substring(first_line_start, sel_end),
tab_sel_contents_find = (e.shiftKey?new RegExp('\n'+TAB_TEXT, 'g'):new RegExp('\n', 'g')),
tab_sel_contents_replace = (e.shiftKey?'\n':'\n'+TAB_TEXT);
tab_sel_contents_replaced = (('\n'+tab_sel_contents)
.replace(tab_sel_contents_find, tab_sel_contents_replace))
.substring(1),
sel_end_new = first_line_start+tab_sel_contents_replaced.length;
this.setSelectionRange(first_line_start, sel_end);
insertText(this, tab_sel_contents_replaced);
this.setSelectionRange(first_line_start, sel_end_new);
});
};
En resumen, las pestañas se insertan al comienzo de las líneas seleccionadas.
JSFiddle: http://jsfiddle.net/iausallc/5Lnabspr/11/
Gist: https://gist.github.com/iautomation/e53647be326cb7d7112d
Ejemplo de uso: $('textarea').enableTabs('\t')
Contras: solo funciona en Chrome como está.
Hay una biblioteca en Github para soporte de pestañas en sus áreas de texto por wjbryant: Tab Override
Así es como funciona:
// get all the textarea elements on the page
var textareas = document.getElementsByTagName('textarea');
// enable Tab Override for all textareas
tabOverride.set(textareas);
Como una opción para el código de kasdega anterior, en lugar de agregar la pestaña al valor actual, puede insertar caracteres en el punto actual del cursor. Esto tiene el beneficio de:
entonces reemplace
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
con
// set textarea value to: text before caret + tab + text after caret
document.execCommand("insertText", false, ' ');
if (e.which == 9) {
e.preventDefault();
var start = $(this).get(0).selectionStart;
var end = $(this).get(0).selectionEnd;
if (start === end) {
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
$(this).get(0).selectionStart =
$(this).get(0).selectionEnd = start + 1;
} else {
var sel = $(this).val().substring(start, end),
find = /\n/g,
count = sel.match(find) ? sel.match(find).length : 0;
$(this).val($(this).val().substring(0, start)
+ "\t"
+ sel.replace(find, "\n\t")
+ $(this).val().substring(end, $(this).val().length));
$(this).get(0).selectionStart =
$(this).get(0).selectionEnd = end+count+1;
}
}
Pruebe esta sencilla función jQuery:
$.fn.getTab = function () {
this.keydown(function (e) {
if (e.keyCode === 9) {
var val = this.value,
start = this.selectionStart,
end = this.selectionEnd;
this.value = val.substring(0, start) + '\t' + val.substring(end);
this.selectionStart = this.selectionEnd = start + 1;
return false;
}
return true;
});
return this;
};
$("textarea").getTab();
// You can also use $("input").getTab();
Tuve que hacer una función para hacer lo mismo, es simple de usar, solo copie este código en su script y use: enableTab( HTMLElement )
HTMLelement es algo así comodocument.getElementById( id )
function enableTab(t){t.onkeydown=function(t){if(9===t.keyCode){var e=this.value,n=this.selectionStart,i=this.selectionEnd;return this.value=e.substring(0,n)+" "+e.substring(i),this.selectionStart=this.selectionEnd=n+1,!1}}}
Cada entrada de un elemento textarea tiene un evento onkeydown. En el controlador de eventos, puede evitar la reacción predeterminada de la tecla de tabulación utilizando event.preventDefault () siempre que event.keyCode sea 9.
Luego ponga un signo de tabulación en la posición correcta:
function allowTab(input)
{
input.addEventListener("keydown", function(event)
{
if(event.keyCode == 9)
{
event.preventDefault();
var input = event.target;
var str = input.value;
var _selectionStart = input.selectionStart;
var _selectionEnd = input.selectionEnd;
str = str.substring(0, _selectionStart) + "\t" + str.substring(_selectionEnd, str.length);
_selectionStart++;
input.value = str;
input.selectionStart = _selectionStart;
input.selectionEnd = _selectionStart;
}
});
}
window.addEventListener("load", function(event)
{
allowTab(document.querySelector("textarea"));
});
html
<textarea></textarea>
$("textarea").keydown(function(event) {
if(event.which===9){
var cIndex=this.selectionStart;
this.value=[this.value.slice(0,cIndex),//Slice at cursor index
"\t", //Add Tab
this.value.slice(cIndex)].join('');//Join with the end
event.stopPropagation();
event.preventDefault(); //Don't quit the area
this.selectionStart=cIndex+1;
this.selectionEnd=cIndex+1; //Keep the cursor in the right index
}
});
Script independiente simple:
textarea_enable_tab_indent = function(textarea) {
textarea.onkeydown = function(e) {
if (e.keyCode == 9 || e.which == 9){
e.preventDefault();
var oldStart = this.selectionStart;
var before = this.value.substring(0, this.selectionStart);
var selected = this.value.substring(this.selectionStart, this.selectionEnd);
var after = this.value.substring(this.selectionEnd);
this.value = before + " " + selected + after;
this.selectionEnd = oldStart + 4;
}
}
}
Si realmente necesita pestañas, copie una pestaña de Word o Bloc de notas y péguela en el cuadro de texto donde desee
1 2 3
12 22 33
Desafortunadamente, creo que eliminan las pestañas de estos comentarios :) Aparecerá como% 09 en su POST o GET