I want the user selection from a text area in my page. I have a context menu that user can use on right-clicking the selection. This is my code to retrieve selected content from a textarea in IE8,
var textComponent = document.getElementById('myTextArea');
var selectedText;
// IE version
if (document.selection != undefined)
{
textComponent.focus();
selectedText= document.selection.createRange();
alert(sel.text);
}
Now I notice that before allowing the blocked content (i.e. the Javascript) I can select a text in the text area and on right click it does not get deselected.
But, when I allow the script, on right clicking the text that I selected gets deselected. Which is why I cannot retrieve the content.
I searched the web but didn't get any solution. Can anyone please tell me what the problem is?
Calling the focus() method of the texbox or using the focus() method of any element on the page will clear the text selection.
Take a look here for a great answer:
Keep text selection when focus changes
Related
Weird issue in Chrome 83 (works fine in FF 78):
I select text in a text area --> it gets highlighted
I click somewhere else --> the text area loses its focus, selected text is still highlighted
the text area is disabled (by javascript) --> selected text still remains highlighted - weird!
Setting the selection range to zero doesn't help. Setting user-select to none doesn't help either. Nor does clearing the window's / document's selection via javascript have any effect. The text highlighted persists. Only thing that helps: Select other text on that web page.
Is this a bug? Can I do anything to actively remove the text selection / text highlight by using css / javascript?
Any help is appreciated.
You should be able to do selection.removeAllRanges() or selection.empty(), depending on how old the browser is. I'm using the mouseout event here because for me, at least, clicking outside of the textarea clears the selection regardless.
document.getElementById('test').addEventListener('mouseout', function() {
document.getElementById('test').disabled = true;
var sel = window.getSelection ? window.getSelection() : document.selection;
if (sel) {
if (sel.removeAllRanges) {
sel.removeAllRanges();
} else if (sel.empty) {
sel.empty();
}
}
});
<textarea id="test"></textarea>
On my page, I have a contenteditable div element. When a specific key is pressed, a function executes:
function bla(element) {
if (getSelectionHtml() != "") {
replaceSelectedText("text");
}
}
getSelectionHtml() checks if something is selected by the user. replaceSelectedText(text) replaces the selected text with a given string. Both functions are working properly.
After the selected text has been replaced, I want to 'cancel' the user's selection, as the selection is now equal to the 'new' string, so just deleting the text is not an option.
I tried this:
element.style.userSelect = "none";
element.style.userSelect = "text;
But it didn't work because userSelect: none doesn't seem to change anything in a div element with contenteditable. Also, this solution looks pretty ugly for such a simple problem.
So, how can I cancel the user's selection?
I think you want to remove selection completely. You can do so once you have replaced the string with
window.getSelection().removeAllRanges()
So basically, once you select the range of content, you can get the range with window.getSelection() method which returns set of details about selected content. It has many functions to alter the range and remove the range completely. To know more, you can read in brief of all supported methods Selection API
Here’s a strange problem I am facing.
I have a contenteditable field and implemented autocomplete functionality for hashtags for it. When a user starts typing a hashtag, they will see a popup box with autocomplete suggestions, like this:
The user can insert a suggested hashtag either using keyboard (selecting it with up/down arrows and pressing on Enter) or by clicking on it. The hashtag will be inserted, and the cursor placed in the end of the hashtag with the following function:
/*
* The function takes a DOM node and the desired caret position
*/
var setCaretPosition = function(node, position) {
node.focus();
var textNode = node.firstChild;
var range = document.createRange();
var sel = window.getSelection();
range.setStart(textNode, position);
range.setEnd(textNode, position);
sel.removeAllRanges();
sel.addRange(range);
};
Now, here’s my problem. The above function works fine if the user selects the hashtag through keyboard (using arrows and pressing on Enter). But if the user clicks on a hashtag, the hashtag is inserted but the focus is lost from the text edit field.
I stepped through the debugger and verified that the DOM element I am trying to focus on and set the cursor in is the same element in both scenarios. But clicking on a hashtag will nonetheless lose the focus on the edit field. I have absolutely no clue as to why this may be happening. Perhaps you could offer any suggestions?
Update: Hmm, I must have made some mistake in my code, because this simple example I made in Codepen works fine.
After re-reading my code for the umpteenth time, I realized that I was calling stopPropagation, but not preventDefault for the mousedown event on the hashtag when I was clicking on it. So it's not surprising that the focus was lost from my text field. I still find it somewhat puzzling that it was not restored with the code snippet I included in my question, but maybe that’s because I was listening to the mousedown event on the hashtag, and the focus, even if it was restored to the text field for a fraction of time, got lost again.
I am working on a website where I would like to be able to display a box containing syntax-highlighted source code for the user to copy. When I click on the box, giving it focus (Chrome shows its focus outline), and type Ctrl+A, the text of the entire page is selected, whereas I would like only the syntax-highlighted source code within the box to be selected.
Is it possible to restrict the range of select all/Ctrl+A to only the text within the box, preferably without using an <iframe>?
My first thought was to try contenteditable. When I click in the box and the editor caret appears, typing Ctrl+A selects only the text within the box, as desired, but it also allows the user to change the code, and I think that the editor-interface aspect of making the box contenteditable will be confusing to users. If I wrap the source code text within a <div> having contenteditable="false" within the <div> having contenteditable="true", then the source code text is read-only, but typing Ctrl+A selects the text of the entire page again.
Here is a test page: http://jsfiddle.net/5crgL/
You can use the document.createRange(); method to select the text from a particular element.
and to handle the ctrl+a you can use the jQuery keydown method and can call the JS code to select the DIV text.
var range = document.createRange();
range.selectNode(document.getElementById(containerid));
window.getSelection().addRange(range);
please see jsfiddle here jsfiddle.
I have been doing research on this simple sounding issue for a couple of days and I have not seen any result.
In a nutshell my problem is as follows: I would like to select text in a some input field, move focus to another field (or generally speaking some other element), but not lose my selected text.
Such a situation could correspond to a use-case in which I select text in a field, right-click and display a custom popup menu, but do not wish to lose focus of selected text, because I want to do some operations on the previously selected text.
A small code test sample would be (for my initial simple scenario - here I am forcing text selection when the second input field gains focus):
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<input type="text" id="text1" size="20" value="Test1"/>
<input type="text" id="text2" size="20" value="Test2"/>
<script>
$('#text2').focus( function (evt) {
var target = $('#text1')[0];
target.select();
console.log('active/focused element: ' + document.activeElement.id);
});
</script>
</body>
</html>
I have been searching SO and web for a solution to this and have not seen much if any help.
I am not sure this is even really possible (due to the link between blur and selection lost and focus and selection). I have seen a style property called preventDeselect, in another SO answer - this does not work and I have not even such documentation or browser support for this.
I am quite struggling with this and would appreciate some help: even saying I can't do this at all or maybe some ways to go.
UPDATE:
Just for the record, my user scenario, which refers to text selection and context menu, is a common one (it slipped my mind to mention): just select some text in this page (or in an input type field) and right click to get the browser's default context menu - my scenario is different in that i want to use a custom menu, but with similar behavior to the browser's context menu - which normally allows to select some text, cut/copy the selection, navigate within the context menu without losing the selected text. So I think it should be possible somehow :) to do all these things with a context menu and still have your selection.
Attempting to answer this part of your question:
Such a situation could correspond to a use-case in which I select text
in a field, right-click and display a custom popup menu, but do not
wish to lose focus of selected text, because I want to do some
operations on the previously selected text.
For this use-case, I created a quick fiddle: http://jsfiddle.net/4XE9a/1/
Note: Am using the same getSelection function from #David's answer.
If you select any text and then right-click on the input, a custom popup menu appears. Click "option 1". You will find that the selection is not lost even though the focus has shifted to that anchor tag.
However, for the second part of your question regarding focus shifting to another textbox, #David's answer suffices.
Update: (after your comments)
Please see this updated fiddle: http://jsfiddle.net/783mA/1/
Now, when you select some text and right-click on the input it will show the custom popup menu with three options. Use tab to navigate and press space or click on the highlighted option. (Due to paucity of time I could not implement up/down arrow keys, but the concept remains the same)
This demonstrates your question in the comment that the selection is still not lost while navigating the menu.
Note: You are wanting to visually keep the selection highlight and not lose the selection while clicking anywhere else. Please note that this is not possible because text selection behavior is OS implemented. Browser, html etc do not play a role here. The text selection is lost as soon as you click anywhere outside the context of selection. This is because the system starts expecting a new selection as soon as you click anywhere outside. However, controls without text surface are exempt. Button, scrollbar arrows etc will not cause selection to lose.
To view this behaviour, in the fiddle, select some text and then click any dropdown on the left pane. The text selection is not lost, even visually for that matter.
This is why in the new fiddle above, I purposely used buttons to demonstrate.
You can save each selection in an interval, then retrieve it when you like. Here is an example that pulls the selection when the input has focus and clears the interval on blur:
function getSelection(elm) {
var start = elm.selectionStart;
var end = elm.selectionEnd;
return elm.value.substring(start, end);
}
$('input').focus(function() {
var self = this;
$(this).data('interval', setInterval(function() {
$(self).data('selection', getSelection(self));
},20));
}).blur(function() {
clearInterval($(this).data('interval'));
});
Now you can stuff like:
$('#text2').focus(function() {
console.log('selection in #text1 was: '+$('#text1').data('selection'));
});
Demo: http://jsfiddle.net/qCCY5/