How can get the selected text from a textbox/textarea if I don't know which one active (focused). I am trying to create a small bookmarklet that will correct the selected text in any type of input on a page.
For the selection, you want selectionStart and selectionEnd.
As for the currently focused element, use document.activeElement.
So as a combination you can use: http://jsfiddle.net/rBPte/1/.
As Tim Down pointed out, you'd need a more complex solution for Internet Explorer version 8 or lower: Caret position in textarea, in characters from the start
function getText(elem) { // only allow input[type=text]/textarea
if(elem.tagName === "TEXTAREA" ||
(elem.tagName === "INPUT" && elem.type === "text")) {
return elem.value.substring(elem.selectionStart,
elem.selectionEnd);
// or return the return value of Tim Down's selection code here
}
return null;
}
setInterval(function() {
var txt = getText(document.activeElement);
document.getElementById('div').innerHTML =
txt === null ? 'no input selected' : txt;
}, 100);
Related
Using Selectize.js in an Angular 9 application for selecting multiple values. Please see links to my UI at the end
https://selectize.github.io/selectize.js/
https://github.com/selectize/selectize.js
I'm trying enable the user to edit the already selected values by simply clicking on the selected item. Selectize has the concept of Plugins by which "features can be added to Selectize without modifying the main library." I'm making use of this concept to override onMouseDown event, where I'm attempting to make the clicked item editable. I have successfully used this method to override onKeyDown to implement editing of the last selected value by clicking on backspace. Please see code pasted at the bottom. this.onKeyDown = (function() {...
https://github.com/selectize/selectize.js/blob/master/docs/plugins.md
The already selected items are shown as a layer of div elements over the underlying input. To make a selected item editable, I'm removing the selected element div from the DOM, populating the underlying input element with the text from the div. That way that particular item becomes a input from a div and is editable.
There are a few issues im running into:
Its not possible to determine the caret position from the div that was clicked. I am able to get the div text and pre-populate the input element but not put the caret at the right place in input. By default the caret shows at the end and the user can move it around.
Corer cases around when a name is already being edited and the user clicks on another item to edit. The selectize library is giving api to insert selections only at the end of the already selected items. For me to keep deleting the div's and populating the input to mimic the editing effect I need to be able to insert at different positions but the library doesnt seem to have the capability for it.
Trying to see if anyone has worked on something similar or has any suggestions. Thanks in advance!
var Selectize = require('./selectize-standalone');
(function () {
Selectize.define('break_on_backspace_custom_plugin', function(options) {
var self = this;
options.text = options.text || function(option) {
return option[this.settings.labelField];
};
this.onMouseDown = (function() {
var original = self.onMouseDown;
return function(e) {
var index, option;
if (!this.$control_input.val().length && this.$activeItems.length > 0) {
index = this.caretPos - 1;
var toBeEdited = this.$activeItems[0];
var toBeEditedText = toBeEdited.textContent;
var text = toBeEditedText.substring(0, toBeEditedText.length - 1);
var prevEdit = localStorage.getItem("currentEdit");
if (index >= 0 && index < this.items.length) {
if (this.deleteSelection(e)) {
localStorage.setItem("currentEdit", text);
this.setTextboxValue(text);
this.refreshOptions(true);
if (prevEdit && prevEdit !== text) {
this.addItem(prevEdit);
}
}
//e.preventDefault();
//return;
}
}
//e.preventDefault();
return original.apply(this, arguments);
};
})();
this.onKeyDown = (function() {
var original = self.onKeyDown;
return function(e) {
var index, option;
if (e.keyCode === 8 && this.$control_input.val() === '' && !this.$activeItems.length) {
index = this.caretPos - 1;
if (index >= 0 && index < this.items.length) {
option = this.options[this.items[index]];
if (this.deleteSelection(e)) {
//option.value = option.value.substring(0, option.value.length - 1);
this.setTextboxValue(options.text.apply(this, [option]));
this.refreshOptions(true);
}
e.preventDefault();
return;
}
}
return original.apply(this, arguments);
};
})();
});
return Selectize;
})();
Pictures of UI and work in progress
Editing last element by clicking backspace
https://i.stack.imgur.com/wULcT.png
Editing middle element by clicking on it
https://i.stack.imgur.com/U5hxd.png
I have to restrict user from deleting such words that are in a particular HTML tag (consider I have a custom tag) in a textarea.
<div>
You can Delete Me
<t>
DontDeleteMe
</t>
</div>
The words which are not in a t tag can be deleted.
I tried few logics nothing helps.
Is there any possibilities to get the selection range of ctrl+del keywords do?
case 46:
{ //DEL
if (range.startOffset == startNode.getLength()) {
var ancestor = endNode.$;
while (ancestor != null) {
var next = ancestor.nextSibling;
if (next != null) {
console.log("Next = " + next);
var node = new CKEDITOR.dom.node(next);
cancelEvent = node.isReadOnly();
break;
}
ancestor = ancestor.parentNode;
}
}
break;
}
Unfortunately, your description is quite poor when it comes to describing exactly what you need with examples so nobody really knows what you want to happen to the text.
Here's my Fiddle I just made.
It notes selected text and the ID of the first highlighted text container.
Select the text and press CTRL + Del.
If you use a text area, you can just let the user delete it but then copy it inside again. But why use a text area if the user shouldnt interfere with it? Did i misunderstand the feature you want?
$(document).on('keydown', function(evt) {
if (evt.ctrlKey && evt.keyCode == 46) { // Ctrl + Del key pressed
if (evt.target.id == 'customTextArea') { // Custom tag selected
$('#customTextArea').text('Don't delete me!'); // Copy old text in text area
}
}
});
I have an old asp.net app originally at .net 2.0 which framework is upgraded to 4.0 (this is not related to my problem, just informing in details) and I'm using Internet Explorer 11. Here I'm facing a problem, I have a text box as shown bellow:
<asp:TextBox ID="txtCost" runat="server" onKeyPress="return GetSelected();" MaxLength="12" TabIndex="6"></asp:TextBox>
In where I'm trying to check on onKeyPress if the user has selected/highlighted any content and trying to get the selected content. To do this I tried bellow code
JS:
function GetSelected() {
var pass = true;
var content = document.getElementById('<%= txtCost.ClientID %>').value;
if (content.length == 2 && key !== 46) {
if (document.getSelection != undefined) { //true, if there is any selected content
//do something with selected content
pass = false;
}
else //if no content selected then return false
{
pass = false;
}
}
return pass;
}
but here if (document.getSelection != undefined) is always true even though there is no text selected in the text box. I need an if condition be true only if there is any selected text in that text box. Well, as I know document.getSelection returns a selectionRange object but I'm not very clear how document.getSelection works. Please help me to fix this.
Bellow are few referrals I followed
link_1,
link_2
I have found this question which provides a solution to compute the exact position of the caret in a text or input box.
For my purposes, this is overkill. I only want to know when the caret is at the end of all the text of an input box. Is there an easy way to do that?
In all modern browsers:
//input refers to the text box
if(input.value.length == input.selectionEnd){
//Caret at end.
}
The selectionEnd property of an input element equals the highest selection index.
<script>
input = document.getElementById('yourinputfieldsid');
if(input.selectionEnd == input.selectionStart && input.value.length == input.selectionEnd){
//your stuff
}
</script>
This checks to see if the caret actually is at the end, and makes sure that it isn't only because of the selection that it shows an end value.
You don't specify what you want to happen when some text is selected, so in that case my code just checks whether the end of the selection is at the end of the input.
Here's a cross-browser function that wil work in IE < 9 (which other answers will not: IE only got selectionStart and selectionEnd in version 9).
Live demo: http://jsfiddle.net/vkCpH/1/
Code:
function isCaretAtTheEnd(el) {
var valueLength = el.value.length;
if (typeof el.selectionEnd == "number") {
// Modern browsers
return el.selectionEnd == valueLength;
} else if (document.selection) {
// IE < 9
var selRange = document.selection.createRange();
if (selRange && selRange.parentElement() == el) {
// Create a working TextRange that lives only in the input
var range = el.createTextRange();
range.moveToBookmark(selRange.getBookmark());
return range.moveEnd("character", valueLength) == 0;
}
}
return false;
}
I have text boxes <input type='text'> that only allow numeric characters and wont let the user enter a dot (.) more than once. Problem is, if the text in the text box is selected, the user intends to overwrite the contents with a dot, hence making it allowed! The question is, how can you tell in javascript whether the text in that text box is selected or not.
Thanks
The following will tell you whether or not all of the text is selected within a text input in all major browsers.
Example: http://www.jsfiddle.net/9Q23E/
Code:
function isTextSelected(input) {
if (typeof input.selectionStart == "number") {
return input.selectionStart == 0 && input.selectionEnd == input.value.length;
} else if (typeof document.selection != "undefined") {
input.focus();
return document.selection.createRange().text == input.value;
}
}
2017 Specific Answer - Faced the same issue recently.
We were allowing users to enter only 3 digits at a time. When the user tried to enter the fourth character we returned false.
This became an issue when the user had a selection and was trying to overwrite the values.
Taking a hint from Tim's answer. I understood that I wanted to see if the selection value was same as the input's value.
In modern browsers I achieved it by doing:
document.getSelection().toString() === input.value // edited
Hope this helps someone.
For anyone who needs the code to get at the selected text within a textbox, here's an enhanced version:
http://jsfiddle.net/9Q23E/527/
function getSelection(textbox)
{
var selectedText = null;
var activeElement = document.activeElement;
// all browsers (including IE9 and up), except IE before version 9
if(window.getSelection && activeElement &&
(activeElement.tagName.toLowerCase() == "textarea" || (activeElement.tagName.toLowerCase() == "input" && activeElement.type.toLowerCase() == "text")) &&
activeElement === textbox)
{
var startIndex = textbox.selectionStart;
var endIndex = textbox.selectionEnd;
if(endIndex - startIndex > 0)
{
var text = textbox.value;
selectedText = text.substring(textbox.selectionStart, textbox.selectionEnd);
}
}
else if (document.selection && document.selection.type == "Text" && document.selection.createRange) // All Internet Explorer
{
var range = document.selection.createRange();
selectedText = range.text;
}
return selectedText;
}
Instead of hitting the wall of digits dots and selections you can climb it easily by checking the value in onchange event.
HTML:
<input type="text" onchange="ValidateNumericValue(this);" />
JS:
function ValidateNumericValue(oInput) {
var blnRequired = true; //set to false if allowing empty value
var sValue = oInput.value;
if (blnRequired && sValue.length == 0) {
alert("Please enter a value");
oInput.focus();
return;
}
var numericValue = parseFloat(sValue);
if (isNaN(numericValue)) {
alert("Value is not a valid number");
oInput.focus();
return;
}
//put back to make 2.15A back to 2.15
oInput.value = numericValue + "";
}
This will check the value when changed (and user go to different element) and when not valid will alert and set focus back.
Live test case: http://jsfiddle.net/yahavbr/NFhay/
You can get the id of the selected element in the page with the following code:
elem_offset = document.getSelection().anchorOffset;
elem = document.getSelection().anchorNode.childNodes[elem_offset];
alert(elem.id);
If you're use case is simply to know whether any text is selected.
The difference between selectionStart and selectionEnd is always zero when no text is selected irrespective of cursor position.
So this should do the trick
const element = document.getElementById('inputbox');
const isTextSelected = element.selectionStart - element.selectionEnd;