Hold ALT and press 0,9 from numeric keypad. It works in google-chrome
This solution allows tabbing in an entire selection like your typical code editor, and untabbing that selection too. However, I haven't figured out how to implement shift-tab when there's no selection.
$('#txtInput').on('keydown', function(ev) {_x000D_
var keyCode = ev.keyCode || ev.which;_x000D_
_x000D_
if (keyCode == 9) {_x000D_
ev.preventDefault();_x000D_
var start = this.selectionStart;_x000D_
var end = this.selectionEnd;_x000D_
var val = this.value;_x000D_
var selected = val.substring(start, end);_x000D_
var re, count;_x000D_
_x000D_
if(ev.shiftKey) {_x000D_
re = /^\t/gm;_x000D_
count = -selected.match(re).length;_x000D_
this.value = val.substring(0, start) + selected.replace(re, '') + val.substring(end);_x000D_
// todo: add support for shift-tabbing without a selection_x000D_
} else {_x000D_
re = /^/gm;_x000D_
count = selected.match(re).length;_x000D_
this.value = val.substring(0, start) + selected.replace(re, '\t') + val.substring(end);_x000D_
}_x000D_
_x000D_
if(start === end) {_x000D_
this.selectionStart = end + count;_x000D_
} else {_x000D_
this.selectionStart = start;_x000D_
}_x000D_
_x000D_
this.selectionEnd = end + count;_x000D_
}_x000D_
});
_x000D_
#txtInput {_x000D_
font-family: monospace;_x000D_
width: 100%;_x000D_
box-sizing: border-box;_x000D_
height: 200px;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
_x000D_
_x000D_
<textarea id="txtInput">_x000D_
$(document).ready(function(){_x000D_
$("#msgid").html("This is Hello World by JQuery");_x000D_
});_x000D_
</textarea>
_x000D_
If you really need tabs copy a tab from word or notepad and paste it in the text box where you want it
1 2 3
12 22 33
Unfortunately I think they remove the tabs from these comments though :) It will show as %09 in your POST or GET
Here's my version of this, supports:
$(function() { _x000D_
var enabled = true;_x000D_
$("textarea.tabSupport").keydown(function(e) {_x000D_
_x000D_
// Escape key toggles tab on/off_x000D_
if (e.keyCode==27)_x000D_
{_x000D_
enabled = !enabled;_x000D_
return false;_x000D_
}_x000D_
_x000D_
// Enter Key?_x000D_
if (e.keyCode === 13 && enabled)_x000D_
{_x000D_
// selection?_x000D_
if (this.selectionStart == this.selectionEnd)_x000D_
{_x000D_
// find start of the current line_x000D_
var sel = this.selectionStart;_x000D_
var text = $(this).val();_x000D_
while (sel > 0 && text[sel-1] != '\n')_x000D_
sel--;_x000D_
_x000D_
var lineStart = sel;_x000D_
while (text[sel] == ' ' || text[sel]=='\t')_x000D_
sel++;_x000D_
_x000D_
if (sel > lineStart)_x000D_
{_x000D_
// Insert carriage return and indented text_x000D_
document.execCommand('insertText', false, "\n" + text.substr(lineStart, sel-lineStart));_x000D_
_x000D_
// Scroll caret visible_x000D_
this.blur();_x000D_
this.focus();_x000D_
return false;_x000D_
}_x000D_
}_x000D_
}_x000D_
_x000D_
// Tab key?_x000D_
if(e.keyCode === 9 && enabled) _x000D_
{_x000D_
// selection?_x000D_
if (this.selectionStart == this.selectionEnd)_x000D_
{_x000D_
// These single character operations are undoable_x000D_
if (!e.shiftKey)_x000D_
{_x000D_
document.execCommand('insertText', false, "\t");_x000D_
}_x000D_
else_x000D_
{_x000D_
var text = this.value;_x000D_
if (this.selectionStart > 0 && text[this.selectionStart-1]=='\t')_x000D_
{_x000D_
document.execCommand('delete');_x000D_
}_x000D_
}_x000D_
}_x000D_
else_x000D_
{_x000D_
// Block indent/unindent trashes undo stack._x000D_
// Select whole lines_x000D_
var selStart = this.selectionStart;_x000D_
var selEnd = this.selectionEnd;_x000D_
var text = $(this).val();_x000D_
while (selStart > 0 && text[selStart-1] != '\n')_x000D_
selStart--;_x000D_
while (selEnd > 0 && text[selEnd-1]!='\n' && selEnd < text.length)_x000D_
selEnd++;_x000D_
_x000D_
// Get selected text_x000D_
var lines = text.substr(selStart, selEnd - selStart).split('\n');_x000D_
_x000D_
// Insert tabs_x000D_
for (var i=0; i<lines.length; i++)_x000D_
{_x000D_
// Don't indent last line if cursor at start of line_x000D_
if (i==lines.length-1 && lines[i].length==0)_x000D_
continue;_x000D_
_x000D_
// Tab or Shift+Tab?_x000D_
if (e.shiftKey)_x000D_
{_x000D_
if (lines[i].startsWith('\t'))_x000D_
lines[i] = lines[i].substr(1);_x000D_
else if (lines[i].startsWith(" "))_x000D_
lines[i] = lines[i].substr(4);_x000D_
}_x000D_
else_x000D_
lines[i] = "\t" + lines[i];_x000D_
}_x000D_
lines = lines.join('\n');_x000D_
_x000D_
// Update the text area_x000D_
this.value = text.substr(0, selStart) + lines + text.substr(selEnd);_x000D_
this.selectionStart = selStart;_x000D_
this.selectionEnd = selStart + lines.length; _x000D_
}_x000D_
_x000D_
return false;_x000D_
}_x000D_
_x000D_
enabled = true;_x000D_
return true;_x000D_
});_x000D_
});
_x000D_
textarea_x000D_
{_x000D_
width: 100%;_x000D_
height: 100px;_x000D_
tab-size: 4;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<textarea class="tabSupport">if (something)_x000D_
{_x000D_
// This textarea has "tabSupport" CSS style_x000D_
// Try using tab key_x000D_
// Try selecting multiple lines and using tab and shift+tab_x000D_
// Try pressing enter at end of this line for auto indent_x000D_
// Use Escape key to toggle tab support on/off_x000D_
// eg: press Escape then Tab to go to next field_x000D_
}_x000D_
</textarea>_x000D_
<textarea>This text area doesn't have tabSupport class so disabled here</textarea>
_x000D_
I made one that you can access with any textarea element you like:
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;
}
}
And the element would look like this:
<textarea onkeydown="textControl(this,event)"></textarea>
You have to write JS code to catch TAB key press and insert a bunch of spaces. Something similar to what JSFiddle does.
Check jquery fiddle:
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');
}
});
?
I had to make a function to do the same, It is simple to use, just copy this code to your script and use: enableTab( HTMLElement )
HTMLelement being something like document.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}}}
Modern way that both is straight-forward and does not lose the ability to undo (Ctrl+Z) the last changes.
$('#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));
}
});
More about execCommand
:
As pointed out in the comment (and while this was once a "modern" solution), the feature has gone obsolete. Quoting the docs:
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.
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;
}
}
}
This solution does not require jQuery and will enable tab functionality on all textareas on a page.
Borrowing heavily from other answers for similar questions (posted below)...
document.getElementById('textbox').addEventListener('keydown', function(e) {
if (e.key == 'Tab') {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
// set textarea value to: text before caret + tab + text after caret
this.value = this.value.substring(0, start) +
"\t" + this.value.substring(end);
// put caret at right position again
this.selectionStart =
this.selectionEnd = start + 1;
}
});
_x000D_
<input type="text" name="test1" />
<textarea id="textbox" name="test2"></textarea>
<input type="text" name="test3" />
_x000D_
Multiple-line indetation script based on @kasdega solution.
$('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;
}
});
Try this simple jQuery function:
$.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();
I was getting nowhere fast trying to use @kasdega's answer in an AngularJS environment, nothing I tried seemed able to make Angular act on the change. So in case it's of any use to passers by, here's a rewrite of @kasdega's code, AngularJS style, which worked for me:
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');
}
});
};
});
and:
<textarea ng-model="mytext" ng-allow-tab></textarea>
For what it's worth, here's my oneliner, for what you all have been talking about in this thread:
<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;}">_x000D_
</textarea>
_x000D_
Testest in latest editions of Chrome, Firefox, Internet Explorer and Edge.
Simple standalone script:
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;
}
}
}
There is a library on Github for tab support in your textareas by wjbryant: Tab Override
This is how it works:
// get all the textarea elements on the page
var textareas = document.getElementsByTagName('textarea');
// enable Tab Override for all textareas
tabOverride.set(textareas);
Based on all that people had to say here on the answers, its just a combination of keydown(not keyup) + preventDefault() + insert a tab character at the caret. Something like:
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
insertAtCaret('txt', '\t')
}
The earlier answer had a working jsfiddle but it used an alert() on keydown. If you remove this alert, then it didnt work. I ve just added a function to insert a tab at the current cursor position in the textarea.
Here s a working jsfiddle for the same: http://jsfiddle.net/nsHGZ/
The simplest way I found to do that in modern browsers with vanilla JavaScript is:
<textarea name="codebox"></textarea>_x000D_
_x000D_
<script>_x000D_
const codebox = document.querySelector("[name=codebox]")_x000D_
_x000D_
codebox.addEventListener("keydown", (e) => {_x000D_
let { keyCode } = e;_x000D_
let { value, selectionStart, selectionEnd } = codebox;_x000D_
_x000D_
if (keyCode === 9) { // TAB = 9_x000D_
e.preventDefault();_x000D_
_x000D_
codebox.value = value.slice(0, selectionStart) + "\t" + value.slice(selectionEnd);_x000D_
_x000D_
codebox.setSelectionRange(selectionStart+2, selectionStart+2)_x000D_
}_x000D_
});_x000D_
</script>
_x000D_
Note that I used many ES6 features in this snippet for the sake of simplicity, you'll probably want to transpile it (with Babel or TypeScript) before deploying it.
The above answers all wipe undo history. For anyone looking for a solution that doesn't do that, I spent the last hour coding up the following for 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);
});
};
In short, tabs are inserted at the beginning of the selected lines.
JSFiddle: http://jsfiddle.net/iausallc/5Lnabspr/11/
Gist: https://gist.github.com/iautomation/e53647be326cb7d7112d
Example usage: $('textarea').enableTabs('\t')
Cons: Only works on Chrome as is.
As an option to kasdega's code above, instead of appending the tab to the current value, you can instead insert characters at the current cursor point. This has the benefit of:
so replace
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
with
// 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;
}
}
I see this subject is not solved. I coded this and it's working very well. It insert a tabulation at the cursor index. Without using 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>
As others have written, you can use JavaScript to capture the event, prevent the default action (so that the cursor does not shift focus) and insert a tab character.
But, disabling the default behavior makes it impossible to move the focus out of the text area without using a mouse. Blind users interact with web pages using the keyboard and nothing else -- they can't see the mouse pointer to do anything useful with it, so it's keyboard or nothing. The tab key is the primary way to navigate the document, and especially forms. Overriding the default behavior of the tab key will make it impossible for blind users to move the focus to the next form element.
So, if you're writing a web site for a broad audience, I'd recommend against doing this without a compelling reason, and provide some kind of alternative for blind users that doesn't trap them in the textarea.
Every input an textarea element has a onkeydown event. In the event handler you can prevent the default reaction of the tab key by using event.preventDefault() whenever event.keyCode is 9.
Then put a tab sign in the right position:
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
}
});
Source: Stackoverflow.com