I am working on a Firefox add-on that converts onscreen temperatures that the use highlights via the user selection. Once it is converted the user selection is replaced with a span HTML element with the ID of alreadyconverted that contains the original temperature and the converted temperature in brackets. An obvious glitch in the code is that the user can then go through and select the converted temperature and infinitely convert it.
What I want is for my Javascript code to detect when the user selection is contained within the span element, overlapping the span element or contains the entire span element. How can I have Javascript detect when the user has selected that span in full or in part?
I saw a similar question on StackOverflow, but it wanted to know when the user selection was contained entirely within the certain element. That's not completely what I want, but I'm not sure what I would need to change in the code to make it suit my needs.
View the JS Fiddle for that thread: http://jsfiddle.net/eT8NQ/
Looking at MDN's documentation for Select, it appears this functionality is already directly supported. See Selection.containsNode().
I've updated your fiddle, and now it properly returns a boolean whether any portion of the element is in your selection.
function elementContainsSelection(el) {
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount > 0) {
return sel.containsNode(el, true);
}
}
return false;
}
This function is defaulted to return false unless the aPartlyContained flag is set. Then partial containment will also return true.
aPartlyContained
When true, containsNode() returns true when a part of
the node is part of the selection.
When false, containsNode() only
returns true when the entire node is part of the selection.
Related
Please do not report this question as a duplicate. I have seen similar questions on stackoverflow, but they don't answer my specific need.
I have some text selected and highlighted on a web page and I'd like to be able to shift-click away from the selected text without extending the selection of text.
I have created a function that sets the variable shiftkey to true whenever the shift key is pressed and I have another function that gets called on a mouse click. The latter function tests if the shiftkey var is set to true to determine if I have a shift-click event. If so, I thought e.preventDefault();
would prevent extending the selected text, but it doesn't!
Using
document.getElementsByTagName("body").style.userSelect = "none";
followed by
window.getSelection().toString();
and finally
document.getElementsByTagName("body").style.userSelect = "auto";
doesn't work either!
Any ideas how this can be made to work?
I found the solution to my problem by reading this page about the selection object and this page about the range object.
I had to assign the original selection to a range and save it to a variable.
var sel = window.getSelection();
var range = sel.getRangeAt(0);
Then, after shift-clicking, the selection would get extended so I would have to empty the selection using either:
sel.empty();
or
sel.removeAllRanges();
Thereafter, I could add the original saved range to the empty selection using:
sel.addRange(range);
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
I am using some JQuery Combobox that you can check out here: https://simpletutorials.com/uploads/1860/demo/index.html
As you can see, you can start typing and get the results filtered.
However, once you have selected a value, when clicking on the arrow to open the list, no other values are shown anymore. So, if I want to change college/state, I need to manually clear the input value. I don't like this, so I want to modify it.
I changed that code and added this JS on the click event of the list:
onclick="document.getElementById('statesCombo-ddi').value='';"
This line basically finds the input by id and sets its value to an empty string.
You can try out by looking for the td element having class "stc-button" (with Chrome, just focus on the arrow of the second combo box) and add my code to the tag.
===EDIT===
You can obtain the same results by adding this code directly to the input:
onclick="this.value=''"
===END EDIT===
This has a weird behavior:
If I SELECT an element from the list, it clears the value and everything works correctly.
If I TYPE some letters and then select a value from the list, no item is shown in the list after clicking.
What's wrong with it?
You can override one of the combo box methods to accomplish this:
STComboBox.prototype.filterAndResetSelected = function() {
this.$('ddi').val('');
this.filterList('');
this.selectRow(0);
this.$('ddl').scrollTop(0);
};
Does this help?
The unminified code is provided, is relatively small (12kb) and is fairly well commented, so you could make this modification directly to the source if you'd like.
Edit: Fixed to clear the input value (as indicated in the comment below)
By reading the source and doing a little debugging with Chrome's inspector (Control+Shift+i), you can find the particular ID of the element you need to clear (#collegesCombo-ddi) in order to clear the input box. Once you've found the element's ID you need to clear (and being very careful with plugins that assign multiple elements with the same ID, which is not allowed in the standard, and an indicator of poorly-written code):
$('#collegesCombo-ddi').val('');
I am making a terminal window in HTML/JavaScript and am using a textarea for input. I would like to prevent sections of the text in the textarea from being deleted. For example, if I had the text in the textarea "C:\>Random Code" I would like to prevent the user deleting the "C:\>" text. Is this possible using javascript?
Assuming jQuery, this script will listen for keystrokes, and if any of the required text can't be found (ie: user tries to delete it) it will add itself right back in there:
var requiredText = 'C:>';
$('textarea').on('input',function() {
if (String($(this).val()).indexOf(requiredText) == -1) {
$(this).val(requiredText);
}
}
You cannot make a section of textarea uneditable (only the whole control).
You can use various JavaScript trickery (listening to keypress events and cancelling event using event.preventDefault if the user wants to do something that you do not want to allow)
Another solution is to, instead of having an undeletable section of the input, to automatically append (or prepend ) a predefined string to the user input (and conveneintly display it for the user in some way).
Update:
So, my solution would look like this:
var requiredText = 'C:>';
$('textarea').on('keyup',function(event) {
if (GetSelectionStart(this) < requiredText.length){
event.preventDefault();
event.stopPropagation();
}
}
Where GetSelectionStart is a function that tells the beginning of the selected text (or caret position, if no text range is selected). For some possible implementations, see e. g. Caret position in textarea, in characters from the start
This function assumes that requiredText is always at the beginning of the string. But of course, it can be adapted for more complex scenarios.
I am trying to get the anchorOffset of text selected by the user in A UIWebView. I have a short Javascript function (below) that is called when the user selects text and chooses an option from a custom contextual menu.
function textPosition()
{
var text = window.getSelection();
var x = text.anchorOffset;
return x;
}
I have a simple paragraph displayed in the UIWebView starting with:
This is a test sentence
Everything works as expected if I select a whole words... eg. if I select This the function returns 0, if I select sentence the function returns 15.
However if I move the handles on the selected text in the UIWebView the anchorOffset is different than expected. Eg. Selecting portions in the order as follows in the first word , this returns the following:
his returns 4
hi returns 1
Thi returns 3
Furthermore this is different depending on the order that I change the selection:
This returns 0
Thi returns 0
hi returns 3
It appears that the anchorOffset is different depending on from which end of the selection I alter the selection.
My questions are:
Am I making an obvious mistake?
Is this expected behaviour?
Is there something I can do to make the result consistent?
Thank you!
I now understand what I was doing wrong. It came from my misunderstanding of what an anchor actually is. I thought the anchorOffset referred to the the first part of a selection geographically but actually it relates to where the moused button was initially pressed (obviously not on a touch screen). The focusOffset relates to where the mouse button was released.
A nicer explanation can be found here:
mozilla developer site
With regard to a UIWebView an initial selection will place the anchor geographically at the start of the selected range and the focus at the end. However each time a selection handle is moved it becomes the focus and the other handle becomes the anchor.