Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use tab to indent in textarea

People also ask

How do you add a tab character in HTML?

Adding Tab Space in HTML Unlike with HTML space, there is no particular HTML tab character you could use. You could technically use the 	 entity as the tab is character 9 in the ASCII. Unfortunately, HTML parsers will simply collapse it into a single space due to the whitespace collapse principle.


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;
  }
});
<input type="text" name="test1" />
<textarea id="textbox" name="test2"></textarea>
<input type="text" name="test3" />

jQuery: How to capture the TAB keypress within a Textbox

How to handle <tab> in textarea?


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.


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.


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;}">
</textarea>

Testest in latest editions of Chrome, Firefox, Internet Explorer and Edge.


Here's my version of this, supports:

  • tab + shift tab
  • maintains undo stack for simple tab character inserts
  • supports block line indent/unindent but trashes undo stack
  • properly selects whole lines when block indent/unindent
  • supports auto indent on pressing enter (maintains undo stack)
  • use Escape key cancel support on next tab/enter key (so you can press Escape then tab out)
  • Works on Chrome + Edge, untested others.

$(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>