Reputation: 50832
I need to get the line number with the cursor in it or better the offset of the cursor in a contenteditable body element.
How can i achieve this?
Upvotes: 4
Views: 2068
Reputation: 50832
I found a solution to my problem, but it will only work if the line-height of all lines are the same. The idea is to insert a dummy element at the caret posititon, calculate the position relative to the body start and then divide this value by the line-height. The result is the number of line the caret is in.
Here some code to get started with:
// get lineheight, eighter line-height or min-height
var $elem = $(ed.getBody().firstElementChild);
var lineHeight = parseInt($elem.css('line-height'), 10) || parseInt($elem.css('min-height'), 10);
var rng = ed.selection.getRng();
rng.collapse(true);
var bm = ed.selection.getBookmark();
var $marker = $(ed.getBody()).find('#'+bm.id);
var elem = ed.getDoc().getElementById(bm.id+'_start');
try {
box = elem.getBoundingClientRect();
}
catch(e){}
var doc = ed.getDoc(),
docElem = doc.documentElement,
body = ed.getBody(),
win = ed.getWin(),
clientTop = docElem.clientTop || body.clientTop || 0,
clientLeft = docElem.clientLeft || body.clientLeft || 0,
scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
top = box.top + scrollTop - clientTop,
left = box.left + scrollLeft - clientLeft;
// set Bookmark
ed.selection.moveToBookmark(bm);
var caret_line = Math.floor( (top) / lineHeight ) + 1;
Upvotes: 2
Reputation: 422
Here is one of my older tools on the subject.
/**
* @description This operation splits the content of a text area based on its cursor position
* and selection.
* @param targetNode This argument expects the text node to be split.
* @return This operation returns an object containing {first, middle, last}.
*/
var splitTextAreaBySelection = function(targetNode)
{
var target = document.getElementById('Area_'+targetNode.uid);
var response = {};
// IE fails this DOM3 operation. Use IE proprietary code here to recover.
// WARNING: This proprietary IE code has Win32 platform dependency!
if (typeof(target.selectionStart) === "undefined")
{
var content = targetNode.content;
// this captures the area selected text.
var r = document.selection.createRange();
if (r !== null) {
// thankfully the middle is easy to get!
response.middle = r.text;
// now we must create a new text range and mess with it until the cursor position can be discovered.
var re = target.createTextRange();
var rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
var cursorPos = rc.text.length;
// now that we have the cursor position, we can abstract the first and last strings from the content.
response.first = content.substr(0,cursorPos);
response.last = content.substr(cursorPos + response.middle.length);
}
else
{
response.first = content;
}
}
else
{
response.first = target.value.substring(0,target.selectionStart);
response.middle = arget.value.substring(target.selectionStart, target.selectionEnd);
response.last = target.value.substring(target.selectionEnd, target.textLength);
}
return response;
};
Upvotes: 0