By using following code I am getting the selected text's startindex and the selected text itself. I am storing them in a local database. I am changing the selected text background color to yellow.
var mainDiv = document.getElementsByTagName("body")[0];
var sel = getSelectionCharOffsetsWithin(mainDiv);
var selectedText = window.getSelection();
location.href = selectedText + '*' + sel.start; // this is to call iOS function.
var range = window.getSelection().getRangeAt(0);
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
span.setAttribute("id", sel.start);
range.surroundContents(span);
Now, I am doing something else, and again I come back to same page. Here now I want to show previously selected text as highlighted.
Use Rangy , nothing beats it , does exactly what your trying
Rangy
Have a look at this demo
Related
I need to split an element after user clicks on it and the attr 'contenteditable' becomes 'true'. This fiddle works for the first paragraph but not second because the latter is in a p tag. Similary in this fiddle you will see that when the element has html tags in it, the counter loses accuracy and hence the text before and after the cursor is not what you'd expect.
The assumption here is that the users will split the data in a way that the help tags will stay intact. As pointed out by dandavis here, e.g. the div has <i>Hello</i> <b>Wo*rld</b>, the user will only need to split the div into two divs, first will have <i>Hello</i> and the second div will have <b>Wo*rld</b> in it.
Html:
<div><mark>{DATE}</mark><i>via email: </i><mark><i>{EMAIL- BROKER OR TENANT}</i></mark></div>
JS:
var $splitbut = $('<p class="split-but">Split</p>');
$(this).attr('contenteditable', 'true').addClass('editing').append($splitbut);
var userSelection;
if (window.getSelection) {
userSelection = window.getSelection();
}
var start = userSelection.anchorOffset;
var end = userSelection.focusOffset;
var before = $(this).html().substr(0, start);
var after = $(this).html().substr(start, $(this).html().length);
The "Split" button is not working as generating the html is not an issue once I get proper "after" and "before" text. Any ideas as to what I am doing wrong here?
Something like this could work for the specific case you describe
$('div, textarea').on('click', function(e) {
var userSelection;
if (window.getSelection) {
userSelection = window.getSelection();
}
var start = userSelection.anchorOffset,
end = userSelection.focusOffset,
node = userSelection.anchorNode,
allText = $(this).text(),
nodeText = $(node).text();
// before and after inside node
var nodeBefore = nodeText.substr(0, start);
var nodeAfter = nodeText.substr(start, nodeText.length);
// before and after for whole of text
var allExceptNode = allText.split(nodeText),
before = allExceptNode[0] + nodeBefore,
after = nodeAfter + allExceptNode[1];
console.log('Before: ', before);
console.log('------');
console.log('After: ', after);
});
Updated demo at https://jsfiddle.net/gaby/vaLz55fv/10/
It might exhibit issues if there are tags whose content is repeated in the whole text. (problem due to splitting)
My current solution is:
Get selected html (include text and html tag), namely: selText
highlightText = <span>selText</span>
Find selText in innerHTML of the body or document (or the element which the mouse dragged in)
Replace with highlightText
But if the document is: a a a a a a and user selects the last a. My function will highlight the first or all a.
Any suggestion?
Thank you.
i think your question is duplicated, anyway i just searched the internet and found this article.
Below the final code to achieve what you ask
function highlightSelection() {
var selection;
//Get the selected stuff
if(window.getSelection)
selection = window.getSelection();
else if(typeof document.selection!="undefined")
selection = document.selection;
//Get a the selected content, in a range object
var range = selection.getRangeAt(0);
//If the range spans some text, and inside a tag, set its css class.
if(range && !selection.isCollapsed)
{
if(selection.anchorNode.parentNode == selection.focusNode.parentNode)
{
var span = document.createElement('span');
span.className = 'highlight-green';
range.surroundContents(span);
}
}
}
I also found this library rangy that is an helper you can use to select text but only works with jquery so i prefer the first vanilla-js solution.
var el = $("<span></span>");
el.text(rangy.getSelection().getRangeAt(0).toString());
rangy.getSelection().getRangeAt(0).deleteContents();
rangy.getSelection().getRangeAt(0).insertNode(el.get(0));
rangy.getSelection().getRangeAt(0).getSelection().setSingleRange(range);
On Range and User Selection
You have to select range using Document.createRange that return a Range object before you can use Range.surroundContents(), you could create a range this way.
var range = document.createRange();
range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);
In practice you follow this guide to understand range and selection tecniques.
The most important point is contained in this code
var userSelection;
if (window.getSelection) {
userSelection = window.getSelection();
}
else if (document.selection) { // should come last; Opera!
userSelection = document.selection.createRange();
}
After this you can use
userSelection.surroundContents()
I want to get selection of block of text (including div's and formatting), I have function 'text_redesign' that should do it and I call it onlick to some button. But it select only the place in button where I clicked, i.e. on button is written "Restructure" and if I click close to 'R', I will get "R span class="someclass_tigran" /span estructure", and if I click close to 't', than I get "Restruc span class="someclass_tigran"/span ture". So it gets the place where I clicked, but not the selected text.
function text_redesign()
{
var text_comonent_area = $("#text_block_1").contents().find('iframe'); //.contents();
//var len = text_comonent_area.value.length;
//var start = text_comonent_area.selectionStart;
//var end = text_comonent_area.selectionEnd;
//var sel = text_comonent_area.value.substring(start, end);
//console.log("start " + start + " end " + end);
var selObj = window.getSelection()
console.log(selObj);
var selRange = selObj.getRangeAt(0);
console.log(selRange);
if(selObj.getRangeAt){ // thats for FF
console.log("sdfsdf33");
var range = selObj.getRangeAt(0);
var newNode = document.createElement("span");
newNode.setAttribute('class', 'someclass_tigran');
range.surroundContents(newNode);
}
}
P.S. I want apply it to iframe, but I tried as inside frame and well as to document and the result is same.
I am new to selection, so if you know where my mistake can be, please, tell and I will google it. Now I have no idea what to search for.
I think it may be better to check the selected text in text_redesign function.
Look at this example:
How to replace selected text with html in a contenteditable element?
I'm getting the selected text from textarea but I can't get it from a div.
I'm trying with document.getElementById('myDiv') but it doesn't work.
To be more specific. When I have text, using this method I can get the selected text
function TestSelection ()
{
if (window.getSelection) {
var selectionRange = window.getSelection();
alert ("The text content of the selection:\n" + selectionRange.toString());
}
}
but I cant specify the div to get it's selected text. Only from this div, not from another.
I tried var value = document.getElementById("myDiv").innerHTML;
and then value.getSelection but it doesn't work too.
Thank you very much!!!
Simply ,do the following :
var ss=getSelection();
ss.baseNode.data.substring(ss.baseOffset,ss.extentOffset);
Use the innerHTML property
var html = document.getElementById('myDiv').innerHTML;
You should use innerHTML property:
var value = document.getElementById("myDiv").innerHTML;
You should use Selection
var selObj = window.getSelection();
window.alert(selObj);
for jquery
var str = $("#myDiv").text();
str is the text
Problem:
I have a CKEditor instance in my javascript:
var editor = CKEDITOR.instances["id_corpo"];
and I need to insert some text programatically, and select some text range afterwards.
I already did insert text through
editor.insertHtml('<h1 id="myheader">This is a foobar header</h1>');
But I need to select (highlight) the word "foobar", programatically through javascript, so that I can use selenium to work out some functional tests with my CKEditor plugins.
UPDATE 1:
I've also tried something like
var selection = editor.getSelection();
var childs = editor.document.getElementsByTag("p");
selection.selectElement(childs);
But doesn't work at all!
How can I do that?
I think that
selection.selectRange()
could do the job, but I'could not figure out how to use it.
There are no examples over there :(
Get current selection
var editor = CKEDITOR.instances["id_corpo"];
var sel = editor.getSelection();
Change the selection to the current element
var element = sel.getStartElement();
sel.selectElement(element);
Move the range to the text you would like to select
var findString = 'foobar';
var ranges = editor.getSelection().getRanges();
var startIndex = element.getHtml().indexOf(findString);
if (startIndex != -1) {
ranges[0].setStart(element.getFirst(), startIndex);
ranges[0].setEnd(element.getFirst(), startIndex + findString.length);
sel.selectRanges([ranges[0]]);
}
You can also do the following:
get the current selection
var selection = editor.getSelection();
var selectedElement = selection.getSelectedElement();
if nothing is selected then create a new paragraph element
if (!selectedElement)
selectedElement = new CKEDITOR.dom.element('p');
Insert your content into the element
selectedElement.setHtml(someHtml);
If needed, insert your element into the DOM (it will be inserted into the current position)
editor.insertElement(selectedElement);
and then just select it
selection.selectElement(selectedElement);
Check out the selectElement() method of CKEDITOR.dom.selection.
http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.dom.selection.html
insert text at cursor point in ck editor
function insertVar(myValue) {
CKEDITOR.instances['editor1'].fire( 'insertText',myValue);
}
this is working for me