Pre-existing JavaScript for using tab to indent textarea contents?
April 23, 2006 3:58 PM   RSS feed for this thread Subscribe

Has anyone previously published a JavaScript methodology for using the Tab key to indent while within HTML textarea controls?

I'd like to use light markup (Markdown) inside a Web form for composing blog entries/essays/etc. However, many elements require whitespace indentation, e.g. blockquotes, nested lists, etc, for which I'd prefer to use the Tab key instead of raping the spacebar (Markdown works best with 4-space indents, otherwise I might just get by with 2 spaces).

One can use JavaScript to implement a "normal" usage of the Tab key, and I have already started on such an implementation. However, I don't want to re-invent the wheel, and find it hard to believe nobody else has done something like this prior. Google has not helped much (tough thing to search for--far too much noise in the results).

Does anyone know of any pre-existing scripts/techniques that accomplish this, or should I forge ahead and continue writing my own?

Please note that I am familiar with the "tabs vs spaces" debate and do not wish for it to repeat here; in addition, I realize that for publicly facing websites, overriding default keyboard behavior can be an accessibility no-no--this is for the admin interface for a personal website.
posted by cyrusdogstar to computers & internet (13 comments total)
I've done a bit of key handler control for some of my work, so it doesn't seem like it would be difficult to implement.

The basic steps would be:
  1. attach event to textarea.onkeypress to intercept strokes
  2. TAB is char code 13 (IIRC)... so when the textarea has focus and the captured key == 13, output 5 spaces (or whatever your tab preferences are), otherwise output the entered key.
  3. (optional) If you plan on displaying this later on in a browser, you'll need to convert those spaces to   characters--otherwise they'll get truncated.


So, something like this:

<textarea id="txtfield" onkeypress="return intercept(event)" />
<script type="javascript" >
  function intercept(event) {
    var key = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
    if (key == 13) {
      return " ";
    } else {
      return key;
    }
  }
</script>
posted by Civil_Disobedient at 4:28 PM on April 23, 2006


Dammit, that first return statement should have more spaces (I should listen to my own advice, particulalry #3!). Anyway, you get the idea. :)
posted by Civil_Disobedient at 4:30 PM on April 23, 2006


If you wanted something that did this automatically for all textareas in your webpage, you might do something like this:

<script type="javascript" >
  window.onload = function() {
  var txtareas = null;
  if ((txtareas = document.getElementsByTagName('TEXTAREA')) != null) {
    for (var i=0; i < txtareas.length; i++) {br>       txtareas.onkeypress = intercept(event);
    }
  }
</script>
posted by Civil_Disobedient at 4:35 PM on April 23, 2006


Dammit, sorry for the mangled code. Too bad Matt hasn't implemented a better <code> handling mechanism for display. :)
posted by Civil_Disobedient at 4:36 PM on April 23, 2006


jesus, cyrus, GET OUT OF MY HEAD. i spent part of last night writing a short subroutine for my homebrew blogware that displays this:

-abc
--ceg
-def

as
posted by lbergstr at 4:39 PM on April 23, 2006


err ... forgot to use entities, there should be some (plaintext) <ul>s in there.
posted by lbergstr at 4:40 PM on April 23, 2006


Yea, I'm having a hard time parsing your post there, lbergstr, although I get the basic idea--hadn't thought of that approach.

Civil, I know how to do it, I was just hoping to find some more-though-out, in-production-use-somewhere code so I wouldn't have to make previously solved mistakes.

However, it looks like I've got it now, at least for the basic case (being able to select+indent, and more easily, being able to un-indent, are now next on my list).

Version 1
posted by cyrusdogstar at 4:53 PM on April 23, 2006


Note, by the way, that while I may change it in the future, I don't plan on bothering making this cross-browser, as again it's currently for personal use.

And the extra form controls on that page are just fluff, I've found it makes things easier (albeit mostly with CSS) to have a "realistic" environment for code I'm developing--been bitten by bizarre bugs in the past that resulted from initial development being done in a pristine setting.
posted by cyrusdogstar at 4:56 PM on April 23, 2006


just to be clear:

-abc
--def
-ceg

turn into:

<ul>
<li>abc</li>
<li><ul><li>def</li></ul></li>
<li>ceg</li>
</ul>

(and if you don't mind, cyrus, i may steal your code and use it as a starting point)
posted by lbergstr at 5:00 PM on April 23, 2006


Oh, sure, go right ahead! I plan to publish it when it's done, presuming nobody answers my original question with a link to something better.

Once the site I'm writing this for is up, it will go up as one of the earlier entries.
posted by cyrusdogstar at 5:09 PM on April 23, 2006


Sorry for managing the thread so much; just had the bright idea that those full-on in-browser WYSIWYG suites might have implemented this already, and it looks like the best-known one--TinyMCE--does have it. Of course, it also has the kitchen sink; I was hoping to find something standalone.
posted by cyrusdogstar at 5:16 PM on April 23, 2006


All right, thread closed, I'm done and relatively happy with what I've accomplished. Thanks for taking an interest, you two; most of my more esoteric AskMes tend to do completely unanswered so I appreciate the attention :)

Version 2 (Accidentally overwrote Version 1, so both links point to the same file; meh)
posted by cyrusdogstar at 6:37 PM on April 23, 2006


I like it. It's a bit glitchy when you tab a selected area, and there's no shift-tab (reverse tabs), but now I'm just nitpicking. :)
posted by Civil_Disobedient at 4:59 PM on April 24, 2006


« Older How is San Diego as a summer v...   |   I want to bike all the way aro... Newer »
This thread is closed to new comments.