Strange behavior of selection - javascript

My JS code:
function getSelectedText(){
if(window.getSelection){
select = window.getSelection().getRangeAt(0);
var st_span = select.startContainer.parentNode.getAttribute("id").split("_")[1];
var end_span = select.endContainer.parentNode.getAttribute("id").split("_")[1];
console.log(select.endContainer);
var ret_urn=[st_span,end_span];
return ret_urn
}
else if(document.getSelection){
return document.getSelection();
}
}
$(document).ready(function() {
$("div#check_button button").click(function () {
var loc = getSelectedText();
console.log(loc);
});
});
Here is my whole html file: http://pastebin.com/acdiU623
It is hard to explain it, so I prepared short movie: http://www.youtube.com/watch?v=tVk4K70JO80
In a few words: when I press left mouse button and hold it to select text/numbers and start selection from the half of letter/number, although this letter/number is not highlighted, it is added to selection. I have to start selection precisely. It is ok with wide letters, but hard with letters like i,j or l.
This is second example of my movie. I pressed left button on 3/4 of length of number 5, although 5 is not highlighted, it is selected.
Tested on FF and Opera.

Ok just tried this demo. and it works flawlessly. it even works on firefox. Just tested opera and safari and it works on both of them as well. Even if i select half a letter or number, it just returns the highlighted text which is what is expected when you make a selection.
try it out on a fresh webpage though just for testing purposes. then when it works and you are satisfied with the results then start making changes to your existing page.
Its a lot more simpler than your code. This is a cross-browser script to get text selected by the user
<script language=javascript>
function getSelText()
{
var txt = '';
if (window.getSelection)
{
txt = window.getSelection();
}
else if (document.getSelection)
{
txt = document.getSelection();
}
else if (document.selection)
{
txt = document.selection.createRange().text;
}
else return;
document.aform.selectedtext.value = txt;
}
</script>
<input type="button" value="Get selection" onmousedown="getSelText()">
<form name=aform >
<textarea name="selectedtext" rows="5" cols="20"></textarea>
</form>
http://www.codetoad.com/javascript_get_selected_text.asp
Hope this helps.
PK

There are multiple different boundary points for a selection that will look the same to the user. What you're seeing is probably the difference between the following, where | is a selection boundary:
<span>5</span><span>|6</span><span>7|</span><span>8</span>
and
<span>5|</span><span>6</span><span>7</span><span>|8</span>
In both cases, calling toString() on the selection will give you the same result ("67").

Related

range.surroundContents in chrome extension is disabling right click

I'm building a chrome extension where selected text can have different highlighting styles applied to it. I used ranges to get this all to work, and I clone the range, put a span around it, and then delete the range and replace it with the cloned one. Everything seems fine except I've somehow managed to disable right clicking by triggering this behavior through the extension. I've narrowed it down the single line of range.surroundContents(span), but here's the full code section:
// Determines the selected text
document.onmouseup = function() {
var selection = document.getSelection();
selection = getSelectedText(color);
};
// Finds the text selected in the page, spans it, and gives it a class
function getSelectedText(inputColor) {
var span = document.createElement('span');
span.setAttribute('class', inputColor);
if(document.getSelection) {
var selection = document.getSelection();
if(selection.rangeCount == true) {
var range = selection.getRangeAt(0).cloneRange();
range.surroundContents(span);
selection.removeAllRanges();
selection.addRange(range);
}
}
}
Is there a way I can counter this? I've already tried using document.oncontextmenu = false directly following the problem line, but that's not bringing back right click. I also tried replacing it with newNode.appendChild(range.extractContents()); range.insertNode(newNode) as recommended by https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents but then instead of highlighting text, it seems to just be removing it from the page.
#wOxxOm answered my question in a comment, but a setTimeout() is what worked. So for anyone else who might have a similar issue in the future:
// Finds the text selected in the page, spans it, and gives it a class
function getSelectedText(inputColor) {
var span = document.createElement('span');
span.setAttribute('class', inputColor);
if(document.getSelection) {
var selection = document.getSelection();
if(selection.rangeCount == true) {
var range = selection.getRangeAt(0).cloneRange();
setTimeout(function(){
range.surroundContents(span);
selection.removeAllRanges();
selection.addRange(range);
}, 100)
}
}
}

Select previous and next words when double clicking blank space in HTML with Javascript

I was trying to change the behaviour of an HTML page with Javascript so whenever I click a blank space in a text (not textArea) between two words, instead of selecting that blank space, it selects the words before and after the blank space. I was trying to do it this way, but I am not able to do it:
function getBothWords() {
if (window.getSelection()) {
var sel = window.getSelection();
var blank = " ";
if(sel == blank) {
...
}
}
}
I also was trying to play with:
window.getSelection().getRangeAt(0)
But still nothing. Any ideas? Thanks :)
When you only click on a blank space, the selection will be collapsed. You can try something like this:
function getBothWords() {
var sel,
range = document.getSelection().getRangeAt(0);
if (range.collapsed) {
range.setEnd(range.startContainer, range.startOffset + 1);
}
sel = range.toString();
if (sel === ' ') {
...
}
}
A live demo at jsFiddle.
You should introspect the selection object and see that there is an anchorNode element available and an anchorIndex.
See the MDN Docs on selection.
The short is you need to look at your anchorNode and anchorOffset.
sel.anchorNode.nodeValue[sel.anchorNode.anchorOffset] might be the first character of your selection. Log the sel object to the console and start poking around. Some simple math should solve the issue from there. Of course it might not be a text node.
Be sure to read the definitions on the page since there are some gotchas that can be confusing.
More to the point, something like this is a dirty hack job:
var subLen = s.focusNode.nodeValue.substr(s.focusOffset).trim().indexOf(' ')+2;
var selectedWordWitSurroundingSpaces = s.focusNode.nodeValue.substr(s.focusOffset, subLen);
There is an amazing method in class Selection called modify() which is created for that purpose. In my case, the solution would be:
function select() {
if (window.getSelection) {
var s = window.getSelection();
var blank = " ";
if(s == blank) {
selectBothWords(s);
}
}
}
function selectBothWords(s) {
s.modify("move", "backward", "word");
s.modify("extend", "forward", "word");
s.modify("extend", "forward", "word");
}
The function select() checks that the selection is a 'blank space' (loosely). Then, the function selectBothWords() uses modify to move the selection one word backwards, then, extend it two words forward.

Set textbox content prefix and postfix via jquery and make it un-editable?

I have an input field for the user to insert their own wordpress shortcode. I would like the characters [ and ] to wrap around their text inside the input box. I don't want them to be able to remove the brackets, and they should always be there.
For example in the input box when they first arrive on the page, it would just have this [] then when they focus on that textbox, the cursor should stay between the brackets, and they should't ever be able to delete the brackets.
UPDATED
For some reason, I cannot get this code to work in jsFiddle, but I have extensively tested this code in the following browsers:
Chrome Version 30.0.1599.101 m - Working
FireFox 19 - Working
FireFox 24 - Working
Safari 5.1.7 - Working.
IE10 - Working
IE9 - Working
IE8 - Partially Working (cannot select text between brackets)
IE7 - Partially Working (cannot select text between brackets)
I did find that there was a reported potential security concern for the older versions of IE when using the createTextRange function which is likely why the code is not working in these versions.
There have been several changes made to the original code that was posted.
<head>
<title></title>
<script>
var setBrackets = function (elem) {
var text = elem.value;
text = text.replace("[", "").replace("]", "");
text = "[" + text + "]";
elem.value = text;
};
var selectRange = function (elem) {
var endPos = elem.value.length - 1;
var startPos = 1;
window.setTimeout(function () {
if (typeof elem.selectionStart === "number") {
elem.selectionStart = startPos;
elem.selectionEnd = endPos;
} else if (typeof elem.createTextRange !== "undefined") {
elem.focus();
var range = elem.createTextRange();
range.collapse(true);
range.select();
}
}, 1);
}
function checkEmpty(elem) {
if (elem.value.length > 2) {
setBrackets(elem);
selectRange(elem);
}
else {
selectRange(elem);
}
}
</script>
<style>
</style>
</head>
<body>
<input type="text" id="test" value="[]" onblur="setBrackets(this)" onfocus="checkEmpty(this)"/>
</body>
I hope this works for you. Please let me know if there's something I can help you with.
Thanks.
Here is a quick solution, when you need to add a brackets in your text-field / phone number field
http://ashfaqahmed.net/jquery-add-prefix-postfix-on-phone-number-field/

Why can't this simple javascript/jquery code alert selected text?

I can't explain the behaviour of the code below. Here's my entire script
<html>
<head>
<script type="text/javascript" language="javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
var tmpText = '';
$(document).ready(function(){
tmpText = '';
$('#btn_bold').click(function(){alert(tmpText);});
$('textarea').bind('mouseup', function(){
tmpText = '';
if(window.getSelection){
tmpText = window.getSelection();
}else if(document.getSelection){
tmpText = document.getSelection();
}else if(document.selection){
tmpText = document.selection.createRange().text;
}
//tmpText = 'hello world';
alert(tmpText);
});
});
</script>
</head>
<body>
<button type="button" id="btn_bold">click</button>
<textarea>This is some text</textarea>
</body>
</html>
Try the following operations:
1) Use your mouse to high light text in the text area. You will notice that javascript alerts you the selected text.
2) Press the click button. You will notice javascript will alert you an empty string.
No uncomment tmpText = 'hello world'; and repeat the above steps. This time, you'll notice both steps 1) and 2) alerts you "hello world".
How come in the first experiment, step 2) does not alert you the same text as step 1)?
I am testing in google chrome
Because it doesn't automatically get converted to string. When you call it straight with alert(), it runs the toString on it, but when you assign to a variable to be later used, it keeps it as selection object and when you try to alert it later on, you presumably won't have that selection active anymore (because you just clicked the button).
Add toString() at the end of each of those selections and it should work as intended.
if(window.getSelection){
tmpText = window.getSelection().toString();
}else if(document.getSelection){
tmpText = document.getSelection().toString();
}else if(document.selection){
tmpText = document.selection.createRange().text;
}
example on jsfiddle
I recall this being explained quite well in the mozilla developer pages under the getSelection bit, if you want a better explanation why it is like this.
EDIT: found the link to the page on mozilla, specifically check what they say under "Notes".
In most browsers, the selection within a textarea (or text input) is handled differently to the selection in the main body of the page. To get the selected text within a textarea, you can use the following, which works in all major browsers:
jsFiddle: http://jsfiddle.net/fxN7p/
Code:
function getTextareaSelectedText(textarea) {
var text = "";
if (typeof textarea.selectionStart == "number") {
text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
} else if (typeof document.selection != "none" && document.selection.type == "Text") {
text = document.selection.createRange().text;
}
return text;
}
Hii...
you have to convert to string the selection... example
window.getSelection().toString()
otherwise you wont could access to the data

How to get selected text from a textbox control with JavaScript

I have a textbox and a link button.
When I write some text, select some of it and then click the link button, the selected text from textbox must be show with a message box.
How can I do it?
When I click the submit button for the textbox below, the message box must show Lorem ipsum. Because "Lorem ipsum" is selected in the area.
If I select any text from the page and click the submit button it is working, but if I write a text to textbox and make it, it's not. Because when I click to another space, the selection of textbox is canceled.
Now problem is that, when I select text from textbox and click any other control or space, the text, which is selected, must still be selected.
How is it to be done?
OK, here is the code I have:
function ShowSelection()
{
var textComponent = document.getElementById('Editor');
var selectedText;
if (textComponent.selectionStart !== undefined)
{ // Standards-compliant version
var startPos = textComponent.selectionStart;
var endPos = textComponent.selectionEnd;
selectedText = textComponent.value.substring(startPos, endPos);
}
else if (document.selection !== undefined)
{ // Internet Explorer version
textComponent.focus();
var sel = document.selection.createRange();
selectedText = sel.text;
}
alert("You selected: " + selectedText);
}
The problem is, although the code I give for Internet Explorer is given on a lot of sites, I cannot make it work on my copy of Internet Explorer 6 on my current system. Perhaps it will work for you, and that's why I give it.
The trick you look for is probably the .focus() call to give the focus back to the textarea, so the selection is reactivated.
I got the right result (the selection content) with the onKeyDown event:
document.onkeydown = function (e) { ShowSelection(); }
So the code is correct. Again, the issue is to get the selection on click on a button... I continue to search.
I didn't have any success with a button drawn with a li tag, because when we click on it, Internet Explorer deselects the previous selection. The above code works with a simple input button, though...
Here's a much simpler solution, based on the fact that text selection occurs on mouseup, so we add an event listener for that:
document.querySelector('textarea').addEventListener('mouseup', function () {
window.mySelection = this.value.substring(this.selectionStart, this.selectionEnd)
// window.getSelection().toString();
});
<textarea>
Select some text
</textarea>
<a href="#" onclick=alert(mySelection);>Click here to display the selected text</a>
This works in all browsers.
If you also want to handle selection via the keyboard, add another event listener for keyup, with the same code.
If it weren't for this Firefox bug filed back in 2001 (yes, 14 years ago), we could replace the value assigned to window.mySelection with window.getSelection().toString(), which works in IE9+ and all modern browsers, and also gets the selection made in non-textarea parts of the DOM.
function disp() {
var text = document.getElementById("text");
var t = text.value.substr(text.selectionStart, text.selectionEnd - text.selectionStart);
alert(t);
}
<TEXTAREA id="text">Hello, How are You?</TEXTAREA><BR>
<INPUT type="button" onclick="disp()" value="Select text and click here" />
For Opera, Firefox and Safari, you can use the following function:
function getTextFieldSelection(textField) {
return textField.value.substring(textField.selectionStart, textField.selectionEnd);
}
Then, you just pass a reference to a text field element (like a textarea or input element) to the function:
alert(getTextFieldSelection(document.getElementsByTagName("textarea")[0]));
Or, if you want <textarea> and <input> to have a getSelection() function of their own:
HTMLTextAreaElement.prototype.getSelection = HTMLInputElement.prototype.getSelection = function() {
var ss = this.selectionStart;
var se = this.selectionEnd;
if (typeof ss === "number" && typeof se === "number") {
return this.value.substring(this.selectionStart, this.selectionEnd);
}
return "";
};
Then, you'd just do:
alert(document.getElementsByTagName("textarea")[0].getSelection());
alert(document.getElementsByTagName("input")[0].getSelection());
for example.
I am a big fan of jQuery-textrange.
Below is a very small, self-contained, example. Download jquery-textrange.js and copy it to the same folder.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>jquery-textrange</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="jquery-textrange.js"></script>
<script>
/* Run on document load */
$(document).ready(function() {
/* Run on any change of 'textarea' **/
$('#textareaId').bind('updateInfo keyup mousedown mousemove mouseup', function() {
/* The magic is on this line **/
var range = $(this).textrange();
/* Stuff into selectedId. I wanted to
store this is a input field so it
can be submitted in a form. */
$('#selectedId').val(range.text);
});
});
</script>
</head>
<body>
The smallest example possible using
<a href="https://github.com/dwieeb/jquery-textrange">
jquery-textrange
</a><br/>
<textarea id="textareaId">Some random content.</textarea><br/>
<input type="text" id="selectedId"></input>
</body>
</html>
// jQuery
var textarea = $('#post-content');
var selectionStart = textarea.prop('selectionStart');
var selectionEnd = textarea.prop('selectionEnd');
var selection = (textarea.val()).substring(selectionStart, selectionEnd);
// JavaScript
var textarea = document.getElementById("post-content");
var selection = (textarea.value).substring(textarea.selectionStart, textarea.selectionEnd);

Categories