Stop caret jumping to bottom of textarea? - javascript

I have a textarea with a lot of text in it, and I have code so that when you press Shift+Enter, it will insert a piece of text. However, at the moment, as soon as that happens, the text scrolls so that the carets at the bottom of the screen.
My insert code:
$("#body textarea").bind('keydown', function(event) {
var caret = $("#body textarea").caret();
if(event.keyCode == 13 && event.shiftKey)
{
var text = "[br]"
insertText("#body textarea", caret.start, caret.end, text, "");
$("#body textarea").caret(caret.start+(text.length), caret.start+(text.length));
}
});
Does anyone know what I can do to stop it forcing the caret to the bottom?
Cheers
BlackWraith

I found on stackoverflow.com same trouble and make sample for you
http://jsfiddle.net/deerua/WAZBQ/

You can set the Caret Position manually after inserting your text:
See http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/:
function doGetCaretPosition (ctrl) {
var CaretPos = 0; // IE Support
if (document.selection) {
ctrl.focus ();
var Sel = document.selection.createRange ();
Sel.moveStart ('character', -ctrl.value.length);
CaretPos = Sel.text.length;
}
// Firefox support
else if (ctrl.selectionStart || ctrl.selectionStart == '0')
CaretPos = ctrl.selectionStart;
return (CaretPos);
}
function setCaretPosition(ctrl, pos){
if(ctrl.setSelectionRange)
{
ctrl.focus();
ctrl.setSelectionRange(pos,pos);
}
else if (ctrl.createTextRange) {
var range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}
ctrl is your textarea-element.
setCaretPosition(document.getElementById("textarea", 0);

Related

Wrap with span if text is selected

I am using the following function to wrap highlighted text with a <span> when the backspace/delete key is hit.
$(document).keydown(function(event) {
var selection = document.getSelection();
typoNumber++;
if (event.keyCode == 8 || event.keyCode == 46) {
event.preventDefault();
var span = document.createElement("span");
span.setAttribute('id', 'typo' + typoNumber);
span.className = "deleted typo";
span.setAttribute('contenteditable', 'false');
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(span);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
});
.deleted.typo {
background: rgba(100,100,100,0.25);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Here is text to experiment with.</div>
I only want the function to run if there is text selected (so that I don't get a bunch of empty <span> elements). I tried changing the first if statement to the following:
if (selection !== '' && event.keyCode == 8 || event.keyCode == 46) {
but that didn't work. Any ideas?
Changing your condition to this should help you:
if(
selection.anchorOffset !== selection.focusOffset
&&
(event.keyCode == 8 || event.keyCode == 46)
)
Fiddle: https://jsfiddle.net/34L49xLr/
getSelection actually returns an object (a SelectionObject) - you can convert that to a string and then check its length to determine whether or not there's any text selected. Something like this:
// Make sure you're initializing this somewhere; this function expects it defined.
var typoNumber = 0;
$(document).keydown(function(event) {
var selection = document.getSelection();
// If there's nothing selected, bail out here.
// If you want to increment typoNumber even with an empty selection,
// move that line above this block.
if (selection.toString().length < 1) {
return;
}
typoNumber++;
if (event.keyCode == 8 || event.keyCode == 46) {
event.preventDefault();
var span = document.createElement("span");
span.setAttribute('id', 'typo' + typoNumber);
span.className = "deleted typo";
span.setAttribute('contenteditable', 'false');
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(span);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
});
/* so we can see where the spans are... */
.deleted.typo {
display: inline-block;
padding: 3px;
background: rgba(100,100,100,0.25);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Here is text to experiment with.</div>

How to get range of characters between # and caret in contenteditable

I have a contenteditable div and it contains other tags and not only plain text. Only one # is allowed in. How can I get the range of the characters between # and caret if such a range exists?
Ha that was easier than I thought!. Based on this easy to overlook question: Div "contenteditable" : get and delete word preceding caret I forked its jsfiddle and here is mine working as expected:
http://jsfiddle.net/52m2thu2/1/
function getWordBetweenAtAndCaret(containerEl) {
var preceding = "",
sel,
range,
precedingRange;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount > 0) {
range = sel.getRangeAt(0).cloneRange();
range.collapse(true);
range.setStart(containerEl, 0);
preceding = range.toString();
}
} else if ((sel = document.selection) && sel.type != "Control") {
range = sel.createRange();
precedingRange = range.duplicate();
precedingRange.moveToElementText(containerEl);
precedingRange.setEndPoint("EndToStart", range);
preceding = precedingRange.text;
}
var lastWord = preceding.match(/#(.+)$/i);
if (lastWord) {
return lastWord;
} else {
return false;
}
}

HTML text area tab support

I am making a web based code editor and am using a textarea for text editing. I want to add tab support to the textarea so that pressing tab doesn't de-focus the element.
I have the textarea defined like this:
<textarea id="codeEdit_txt" rows="50" cols="80" onkeydown="return codeEdit_keyDown(event);">
and the function codeEdit_keyDown defined as:
function codeEdit_keyDown(e) {
if (e.keyCode == 9) {
return false;
}
}
This prevents the tab key press from de-focusing the textarea, though it doesn't leave the tab character behind. While I was trying to get this to work initially, I noticed that if I defined the function as below, it would put a tab character at the cursor position.
function codeEdit_keyDown(e) {
if (e.keyCode == 9) {
alert("");
return false;
}
}
My two questions are:
Why does adding the alert cause a tab to be added?
Is there a way to add the tab at the cursor without having to find the cursor
position, split the text in the texarea and manually add a tab
character (and without having to have an alert every time the user pressed tab)?
Thanks
EDIT: This only seems to work in Chrome, not in IE, Safari or Firefox
See this question:
https://stackoverflow.com/a/13130/420001
You're looking for .preventDefault();
EDIT: A fiddle.
EDIT 2: A better fiddle, thanks to rainecc.
The other answer is nice, but it ends tabs at the end.
I looked up how to add the tab at the cursor location, and added that to the solution.
You can find the working code here: http://jsfiddle.net/felixc/o2ptfd5z/9/
Code inline as a safeguard:
function insertAtCursor(myField, myValue) {
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
//MOZILLA and others
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
myField.selectionStart = startPos + myValue.length;
myField.selectionEnd = startPos + myValue.length;
} else {
myField.value += myValue;
}
}
function addTabSupport(elementID, tabString) {
// Get textarea element
var myInput = document.getElementById(elementID);
// At keydown: Add tab character at cursor location
function keyHandler(e) {
var TABKEY = 9;
if(e.keyCode == TABKEY) {
insertAtCursor(myInput, tabString);
if(e.preventDefault) {
e.preventDefault();
}
return false;
}
}
// Add keydown listener
if(myInput.addEventListener ) {
myInput.addEventListener('keydown',keyHandler,false);
} else if(myInput.attachEvent ) {
myInput.attachEvent('onkeydown',this.keyHandler); /* damn IE hack */
}
}
// easily add tab support to any textarea you like
addTabSupport("input", "\t");
<h1>Click in the text and hit tab</h1>
<textarea id="input" rows=10 cols=50>function custom(data){
return data;
}</textarea>
Here's what I used for my own editor (using some other answers) :
function insertAtCursor (el, text) {
text = text || '';
if (document.selection) {
// IE
el.focus();
var sel = document.selection.createRange();
sel.text = text;
} else if (el.selectionStart || el.selectionStart === 0) {
// Others
var startPos = el.selectionStart;
var endPos = el.selectionEnd;
el.value = el.value.substring(0, startPos) +
text +
el.value.substring(endPos, el.value.length);
el.selectionStart = startPos + text.length;
el.selectionEnd = startPos + text.length;
} else {
el.value += text;
}
};
document.querySelector("#editor").addEventListener("keydown", function(e) {
var TABKEY = 9;
if(e.keyCode == TABKEY) {
insertAtCursor(this, "\t");
if(e.preventDefault) {
e.preventDefault();
}
return false;
}
}, false);

JS/jQuery: How to highlight or select a text in a textarea?

I don't want to highlight text (by changing background color to yellow - NO), I just want to select a portion of the text inside textarea, exactly as if the user clicked and hold the click then moved the mouse to highlight only a portion of the text
How to do that? is it possible?
http://help.dottoro.com/ljtfkhio.php
Example 1 would be relevant in your case:
function Select () {
var input = document.getElementById ("myText");
if (input.selectionStart === undefined) { // Internet Explorer
var inputRange = input.createTextRange ();
inputRange.moveStart ("character", 1);
inputRange.collapse ();
inputRange.moveEnd ("character", 1);
inputRange.select ();
}
else { // Firefox, Opera, Google Chrome and Safari
input.selectionStart = 1;
input.selectionEnd = 2;
input.focus ();
}
}
In non-IE browsers, this is easy: you can set the values of the textarea's selectionStart and selectionEnd properties, or use the setSelectionRange() function (although I've never been clear why that method is present: it seems unnecessary). In IE, however, it's a bit more complicated. Here's a cross-browser function that does it:
var setInputSelection = (function() {
function offsetToRangeCharacterMove(el, offset) {
return offset - (el.value.slice(0, offset).split("\r\n").length - 1);
}
return function(el, startOffset, endOffset) {
el.focus();
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
el.selectionStart = startOffset;
el.selectionEnd = endOffset;
} else {
var range = el.createTextRange();
var startCharMove = offsetToRangeCharacterMove(el, startOffset);
range.collapse(true);
if (startOffset == endOffset) {
range.move("character", startCharMove);
} else {
range.moveEnd("character", offsetToRangeCharacterMove(el, endOffset));
range.moveStart("character", startCharMove);
}
range.select();
}
};
})();
var textarea = document.getElementById("foo");
// Select the text between the second and third characters inclusive
setInputSelection(textarea, 1, 3);
you can use this plugin
http://www.dennydotnet.com/post/TypeWatch-jQuery-Plugin.aspx
you have a callback function after the user has "finished" typing , and more things..

Find space at cursor in TEXTAREA

Is there anyway to check if the character at the cursor in TEXTAREA is a "space"? If it is, return TRUE. Let me know how to do this using jQuery.
Thanks
This works in recent versions of the main browsers and has the added bonus of not requiring jQuery or any other library:
function nextCharIsSpace(textArea) {
var selectedRange, range, selectionEndIndex;
// Non-IE browsers
if (typeof textArea.selectionEnd == "number") {
selectionEndIndex = textArea.selectionEnd;
}
// IE is more complicated
else if (document.selection && document.selection.createRange) {
textArea.focus();
selectedRange = document.selection.createRange();
range = selectedRange.duplicate();
range.moveToElementText(textArea);
range.setEndPoint("EndToEnd", selectedRange);
selectionEndIndex = range.text.length;
}
return textArea.value.charAt(selectionEndIndex) === " ";
}

Categories