in the example below pls place cursor at the start of any line and pressTab
key
this works fine
I want the same if multiple lines are selected at once and also delete one tab if Shift Tab
is pressed
Probably I need an array of selected lines but have no idea how to get them
Please help
$('#wrap').on('keydown', function(e){
if(e.keyCode === 9){
e.preventDefault();
var range = window.getSelection().getRangeAt(0);
var tab = document.createTextNode("\u00a0");
range.insertNode(tab);
range.setStartAfter(tab);
}
});
.wrap{padding:0 14px 9px 14px; white-space:pre-wrap; background:orange; outline:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrap' id='wrap' contenteditable>
lorem ipsum
dolor sit
amet
</div>
CodePudding user response:
Consider the following.
$('#wrap').on('keydown', function(e) {
if (e.keyCode === 9) {
e.preventDefault();
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
var range = window.getSelection().getRangeAt(0);
var tab = document.createTextNode("\t");
if (range.collapsed) {
range.insertNode(tab);
range.setStartAfter(tab);
} else {
var content = range.toString(),
count = (content.match(/\n/g) || []).length,
start = 0,
end = content.indexOf("\n");
range.deleteContents();
var newContent = document.createDocumentFragment();
for (var i = 0; i <= count; i ) {
newContent.append("\t" content.substring(start, end));
if (i != count) {
newContent.append("\n");
}
start = end 1;
end = content.indexOf("\n", start);
if (end == -1) {
end = content.length;
}
}
range.insertNode(newContent);
}
}
}
});
.wrap {
padding: 0 14px 9px 14px;
white-space: pre-wrap;
background: orange;
outline: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrap' id='wrap' contenteditable>
lorem ipsum
dolor sit
amet
</div>
Here you can see where we examine the Selection. If it is just a Single line, nothing selected or Collapsed, then we just add a Tab character (\t
) at the front of that line. If it is multiple lines, then we need to add a Tab character to each line in the selection.
This means we need to define a Line, so from the Start of the line to the End of Line (EOL), usually Return Carriage (\r
) and New Line (\n
), sometimes just the New Line. If we look for the New Line character, we ensure each line can be found.
So if the selection is:
lorem ipsum\r\n
dolor sit
You want the following output:
\tlorem ipsum\r\n
\tdolor sit
First we find all the Lines and get a count
, so that we can iterate each and append the Tab character. We collect each line, modify it, and place it into a Document Fragment for entering later. As needed, we add the New Line character back.
If you want to use an Array, then .split("\n")
would be a good way to do this.
$('#wrap').on('keydown', function(e) {
if (e.keyCode === 9) {
e.preventDefault();
var range = window.getSelection().getRangeAt(0);
var content = range.toString().split("\n");
range.deleteContents();
var newContent = document.createDocumentFragment();
$.each(content, function(i, line) {
newContent.append("\t" line);
if (i != (content.length - 1)) {
newContent.append("\r\n");
}
});
range.insertNode(newContent);
}
});
.wrap {
padding: 0 14px 9px 14px;
white-space: pre-wrap;
background: orange;
outline: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrap' id='wrap' contenteditable>
lorem ipsum
dolor sit
amet
</div>