I'm trying to read in the value of selected text within a text area. Here is my code:
function readSelected(id)
{
textarea = document.getElementById(id);
if (document.selection)
{ //Code for IE
textarea.focus();
sel = document.selection.createRange();
alert(sel.text);
}
else
{ // Code for Mozilla Firefox
var len = textarea.value.length;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var scrollTop = textarea.scrollTop;
var scrollLeft = textarea.scrollLeft;
sel = textarea.value.substring(start, end);
alert(sel);
}
}
HTML:
<textarea id="txt1" rows="10"></textarea>
<a onclick="readSelected('txt1');">Get Selected</a>
When you click the button, a popup should occur telling you what the selected text is.
The code works in Firefox, but I can't get it to work in IE8.
The problem is that clicking on the <a> element destroys the selection. You could use an unselectable button instead:
<input type="button" value="get" onclick="readSelected('txt1');" unselectable="on">
There are other minor issues with your code
You should declare all your variables, otherwise they end up leaking into the global scope. sel and textarea are the offenders here.
scrollTop and scrollLeft are redundant.
You should test for the selectionStart and selectionEnd properties first, since they're the standard (HTML 5 specifies them and IE 9 will support them).
Here's my rewritten version:
function readSelected(id) {
var sel = "", el = document.getElementById(id);
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
sel = el.value.slice(el.selectionStart, el.selectionEnd);
} else if (document.selection && document.selection.createRange) {
el.focus();
sel = document.selection.createRange().text;
}
alert(sel);
}
Did you try with onmousedown instead of onclick ?
Related
This is my editor content:
<h1>Heading 1<h1>
<p>Paragraph</p>
<h2>Heading 2</h2>
Now if i select text in the editor, is there a chance to get a list of all the elements involved in this selection? For example if i select a portion of Heading 1 and Paragraph i would like to get an array (h1, p) or at least an object where i can see which elements are in the selection.
Ive already tried most of the functions described here http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection but most of the time i only get the first element of the selection.
i have adapted a function i had for the same
$("textarea").select(function() {
var textComponent = $(this)[0]; //element identifier
var selectedText;
// IE version
if (document.selection !== undefined)
{
textComponent.focus();
var sel = document.selection.createRange();
selectedText = sel.text;
}
// Mozilla version
else if (textComponent.selectionStart !== undefined)
{
var startPos = textComponent.selectionStart;
var endPos = textComponent.selectionEnd;
selectedText = textComponent.value.substring(startPos, endPos);
}
$("p").html("You selected: " + selectedText);
});
check here: https://jsfiddle.net/ees8bupq/1/
This question already has answers here:
window.getSelection() of textarea not working in firefox?
(2 answers)
Closed 3 months ago.
How can I get the selected text (in a contenteditable div) in Firefox ? It would be enough for recent versions, no need to cover old versions.
Say I have a contenteditable div that looks like the below and someone selects a text there and then hits a button, how can I copy the selected text to the clipboard or a variable ?
Example:
<div class='editInput' id='editInput'>Some awesome text</div>
My current function (working in IE):
function GetSelection()
{
if (typeof window.getSelection != "undefined")
{
var sel = window.getSelection();
if (sel.rangeCount)
{
var container = document.createElement('div');
for (var i = 0, len = sel.rangeCount; i < len; ++i)
container.appendChild(sel.getRangeAt(i).cloneContents());
return container.innerHTML;
}
}
else if (typeof document.selection != 'undefined')
if (document.selection.type == 'Text')
return document.selection.createRange().htmlText;
return '';
}
var selectedText = "" + window.getSelection();
The other suggestions didn't work for me, but the following did:
var textArea = document.getElementById('input_text_area');
var selectedText = textArea.value.substring(textArea.selectionStart,textArea.selectionEnd);
This other answer links to some background on why the above is necessary and why window.getSelection() doesn't work on Firefox, for example.
I have been struggling the selectionStart and selectionEnd attributes of textarea to make them work with contenteditable div element. I have checked a lot of related articles on google and on SO but to no avail. I have something similar to the following which is working for textarea perfectly. But I want this one to work with contenteditable div.
function replaceVal(node, val, step){
//...
var cursorLoc = node.selectionStart;
node.value = node.value.substring(0, node.selectionStart - step) + value +
node.value.substring(node.selectionEnd, node.value.length);
node.scrollTop = scrollTop;
node.selectionStart = cursorLoc + value.length - step;
node.selectionEnd = cursorLoc + value.length - step;
//...
}
How can this be modified so that it will work with contenteditable div element instead of textarea?
Try this, it returns the selected text, no matter if it's contentEditable or not.
function GetSelectedText() {
if (document.getSelection) { // all browsers, except IE before version 9
var sel = document.getSelection();
// sel is a string in Firefox and Opera,
// and a selectionRange object in Google Chrome, Safari and IE from version 9
// the alert method displays the result of the toString method of the passed object
alert(sel);
}
else {
if (document.selection) { // Internet Explorer before version 9
var textRange = document.selection.createRange();
alert(textRange.text);
}
}
}
<div>Test Example Microsoft T-shirt box</div>
<button onClick="GetSelectedText()">Get text</button>
I make this example in jsfiddler, see that
enter link description here
Use Selection object from getSelection() method to get baseOffset and extentOffset of contentEditable elements
var sel = document.getSelection();
node.value = node.value.slice(0, sel.baseOffset - step) + value + node.value.slice(sel.extentOffset);
This answer uses Selection#modify, which is non-standard, but at least, I suggest you to use "insertText" command:
function replaceVal(val, step) {
var selection = window.getSelection();
for (var i = 0; i < step; i += 1) {
selection.modify('extend', 'backward', 'character');
}
document.execCommand('insertText', false, val);
}
<label for="editable">Editable:</label>
<div contenteditable="true" id="editable">Test test test</div>
<label for="step">Step:</label>
<input type="number" id="step" name="step" min="0" step="1" value="0" />
<button onClick="replaceVal('insertion', Number(document.getElementById('step').value))">Get text</button>
Within a contenteditable DIV, I want to determine, if the user made a selection from left-to-right or from right-to-left. Does someone have a Javascript solution for the Browsers Firefox, Chrome, Safari, Opera? And when possible, also one for IE?
<div id="editor" contenteditable>
Selection from Cursor end | here <strong>over bold</strong> to Cursor start | here.
</div>
I prepared the code in jsFiddle here: http://jsfiddle.net/ecUka/
Thank's in advance :-)
Here's a function that uses the fact that setting the end of a DOM Range to be at an earlier point in the document than the start of the range will collapse the range.
Demo: http://jsfiddle.net/97MDR/17/
Code:
function isSelectionBackwards() {
var backwards = false;
if (window.getSelection) {
var sel = window.getSelection();
if (!sel.isCollapsed) {
var range = document.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
backwards = range.collapsed;
}
}
return backwards;
}
Demo:
function isSelectionBackwards() {
var backwards = false;
if (window.getSelection) {
var sel = window.getSelection();
if (!sel.isCollapsed) {
var range = document.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
backwards = range.collapsed;
}
}
return backwards;
}
document.addEventListener("selectionchange", function() {
document.getElementById("selReport").textContent = isSelectionBackwards();
});
<p>Select something forwards and backwards in here</p>
<p>Selection is backwards: <strong id="selReport">false</strong><p>
Unless you need to support Internet Explorer <9, which seems highly unlikely in 2023, you can safely ignore the rest of this answer, which I'm leaving here for posterity.
The above works in all major browsers except IE < 9, which does not support the same Range and Selection APIs as other browsers.
For IE < 9, there is simply nothing in the selection API to tell you about the selection direction. The best I can suggest is using the selectionchange event to keep track of the previously selected range and see which end has changed each time it fires. It seems to work in the following example but has had no testing apart from that, so use at your own risk.
Demo: http://jsfiddle.net/97MDR/18/
Additional code specific to IE < 9 that won't work in modern browsers:
var selectedRange, selectionBackwards;
document.onselectionchange = function(evt) {
evt = evt || window.event;
var sel = document.selection;
if (sel && sel.type !== "Control") {
if (sel.type == "Text") {
// Selection is not collapsed, so compare range end points
var newRange = sel.createRange();
if (selectedRange) {
var startChanged = (newRange.compareEndPoints("StartToStart", selectedRange) != 0);
var endChanged = (newRange.compareEndPoints("EndToEnd", selectedRange) != 0);
if (startChanged && !endChanged) {
selectionBackwards = true;
} else if (endChanged && !startChanged) {
selectionBackwards = false;
} else if (startChanged && endChanged) {
// Both ends have changed, which is confusing.
// I suspect this can happen when the selection snaps
// to words. In this case we can tell nothing, so leave
// selectionBackwards alone.
} else {
// Neither end has changed, so we can tell nothing.
}
}
selectedRange = newRange;
} else {
// Selection is collapsed
selectionBackwards = false;
}
}
};
range.setStart(anchorNode, anchorOffset);
range.setEnd(focusNode, focusOffset);
if(range.collapsed == false){
colsole.log('forward Selected');
}else{
colsole.log('backward Selected');
}
In my site I am using a WYSIWYG editor that uses an iframe.
When I select a text with double click in order to add a link to it, in Chrome, Safari and Firefox the selected text is the right one and the link is added.
However, when I click an image instead, the selection is done only in Firefox. Chrome and Safari have an empty selection and in order to select the image and add a link on it, I have to drag the mouse over it, like a manual select.
My code is:
var sel = parent.document.getElementById('myframe').contentWindow.document.getSelection();
if (sel.rangeCount > 0) {
var range = sel.getRangeAt (0);
var docFragment = range.cloneContents ();
var tmpDiv = document.createElement ("div");
tmpDiv.appendChild (docFragment);
selHTML = tmpDiv.innerHTML;
}
if (selHTML != '') {
parent.document.getElementById('myframe').contentWindow.document.execCommand(id,false,value);
}
Is there any way to solve this problem?
Thanks in advance.
I change the code to that one according to #Tim suggestions:
var iframeWin = parent.document.getElementById('myframe').contentWindow;
var iframeDoc = iframeWin.document;
var sel = iframeWin.getSelection();
var range = iframeDoc.createRange();
var referenceNode = document.getElementsByTagName("img").item(0);
range.selectNode(referenceNode);
sel.removeAllRanges();
sel.addRange(range);
parent.document.getElementById('myframe').contentWindow.document.execCommand(id,false,value);
But still not works. Any more suggestions?
You could just do this manually using the dblclick event, but beware of breaking the regular image resize handles you get in non-WebKit browsers.
Live demo: http://jsfiddle.net/x49hv/3/
Code:
var iframeWin = parent.document.getElementById('myframe').contentWindow;
var iframeDoc = iframeWin.document;
// Prevent errors in IE < 9, which does not support DOM Range and Selection
if (iframeWin.getSelection && iframeDoc.createRange) {
iframeDoc.ondblclick = function(e) {
if (e.target.nodeName.toLowerCase() == "img") {
var sel = iframeWin.getSelection();
var range = iframeDoc.createRange();
range.selectNode(e.target);
sel.removeAllRanges();
sel.addRange(range);
}
};
}