Installation loses carriage position on <pre class = "prettyprint-override"> element on pressing TAB key
I have a pre with contentEditable="true" on my webpage and I try to make it append "\t" when I press <TAB> . I found other plugins for this, but they only worked on <textarea> .
So the problem is that when I add text to <pre> via jQuery, it loses the caret position. I was sure that this was losing focus, but it wasnβt. Therefore, $("pre").focus() do nothing.
I tried to blur it first, but this is impractical because the carriage will return to a different position depending on the browser. please help ...: P,
My code is here: http://jsfiddle.net/parisk/kPRpj/
Try instead of document.execCommand . Here is a demo . In short:
$("pre").keydown(function(e){ if (e.keyCode==9) { e.preventDefault(); document.execCommand('InsertHTML', false, '\t'); } }); try first
$("pre").keydown(function(e){ if (e.keyCode==9) { e.preventDefault(); $("pre").append("\t"); } }); to insert a tab. it inserts a tab after your cursor
then in chrome
var myselection = document.getSelection(); myselection.extend(jQuery("pre")[0].lastChild, jQuery("pre")[0].lastChild.length) myselection.collapseToEnd(); in IE8
var myselection = document.selection; myselection.extend(jQuery("pre")[0].lastChild, jQuery("pre")[0].lastChild.length) myselection.collapseToEnd(); should get you at the end.
(together)
$("pre").keydown(function(e){ if (e.keyCode==9) { e.preventDefault(); $("pre").append("\t"); var myselection = null; if(document.getSelection) { myselection = document.getSelection(); } else if (document.selection) { myselection = document.selection; } if(myselection != null) { myselection.extend(jQuery("pre")[0].lastChild, jQuery("pre")[0].lastChild.length) myselection.collapseToEnd(); } } }); EDIT would also be safer to add to the test to see if lastChild is null and different. Also in the jQuery("pre") keydown function, it would be better to be jQuery(this) and put in a variable if you use more than once. (which is an example, but I'm too lazy)
For your question only, jquery caret libraries are pretty good for encapsulating quirks around different browsers (namely IE): http://plugins.jquery.com/plugin-tags/caret
You can always use this to get the index of all tab stops and then clear them later ...
James Houri's answer always puts a carriage at the end of the <pre> , which is undesirable when the user presses the tab in the middle of the text.
Here is a modified version that fixes this problem: http://jsfiddle.net/kPRpj/12/ . It would be pretty trivial to tab indent the line instead of adding the tab character at the caret position. For this you replace
container.textContent = text.substring(0,start)+'\t'+text.substring(end); from
var left = text.substring(0,start); var lastLine = left.lastIndexOf("\n"); if (lastLine == -1) lastLine = 0; container.textContent = left.substring(0,lastLine)+'\t'+text.substring(lastLine); I put a version that behaves this way on jsfiddle. However, you may need to overcome some inconsistencies in the management of '\n\r' . For example, I see that chrome sees each line as a separate text node, which is pretty unexpected. I have not tested it in other browsers.