I created a textarea and a button. When the button is clicked, I want to add the letter 'a' at the current position of the cursor in the textarea. Below is my current code:
$('button.buttonA').click(function(){
var cursorPos = $('textarea.formInsideMenu').prop('selectionStart');
var textCurrent = $('textarea.formInsideMenu').val();
var textBefore = textCurrent.substring(0, cursorPos);
var textAfter = textCurrent.substring(cursorPos, textCurrent.length);
$('textarea.formInsideMenu').val(textBefore + 'a' + textAfter);
});
The above code works fine, (inserts an 'a' at the correct position), when the focus is on the textarea; but as soon as I click on the button, I lose focus of the textarea and the cursor is no longer showing. If I click on the button again after this, 'a' is appended at the very end of the text, (it seems like the cursor is moved to the end of the text). Is there anyway to keep track of where the cursor is inside the textarea even when something else has been clicked on and the textarea has lost focus?
Once you're done with the insert, you need to focus the textarea and set the caret position back:
$('button.buttonA').click(function() {
var area = $('textarea.formInsideMenu'),
curPos = area.prop('selectionEnd');// at the caret **or after selected text**
area.val( area.val().substring(0, curPos) + 'a' + area.val().substring(curPos) )
.focus()
.prop({'selectionStart': curPos+1, 'selectionEnd': curPos+1});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="buttonA">Add an a</button> <br>
<textarea class="formInsideMenu"></textarea>
This version uses javascript only after returning the dom object from jQuery:
$('button.buttonA').click(function(){
var text = $('textarea.formInsideMenu').get(0);
var start = text.selectionStart;
text.value = text.value.slice(0,start) + 'a' + text.value.slice(start);
text.setSelectionRange(start+1,start+1);
text.focus();
});
Fiddle here
Use setSelectionRange after inserting the 'a'.
$('button.buttonA').click(function(){
var cursorPos = $('textarea.formInsideMenu').prop('selectionStart');
var textCurrent = $('textarea.formInsideMenu').val();
var textBefore = textCurrent.substring(0, cursorPos);
var textAfter = textCurrent.substring(cursorPos, textCurrent.length);
$('textarea.formInsideMenu').val(textBefore + 'a' + textAfter);
var elem = document.getElementsByClassName("formInsideMenu")[0];
elem.setSelectionRange(cursorPos, cursorPos + 1);
});
https://jsfiddle.net/ny82n5kn/
You can make a change event on the textarea, where you sore the position of the cursor, like this:
var cursorPos;
$('textarea.formInsideMenu').on('change', function(){
cursorPos = $(this)).prop('selectionStart');
};
Now it will be avaiable in the clickhandler.
Related
Explanation
I have a textarea and a button. When I click the button, I want to insert text into the textarea. However, the text that I insert depends upon the current focus of the texteara. Here are some cases:
Cases
(As of the time that the button is clicked)
Textarea focused
Insert text where the cursor is, as-is
Textarea unfocused
Insert text at the end of the textarea (ie add a newline to the inserted text)
Example / Attempt
Here is a fiddle with my example implementation:
https://jsfiddle.net/reL9ro6L/1/
$(document).ready(function() {
$('button').click(function() {
var $text = $('textarea');
var currentValue = $text.val(),
len = currentValue.length,
isTextAreaFocused = $text.is(':focus'),
optionalNewline = isTextAreaFocused ? '' : '\n';
var start = $text[0].selectionStart,
end = $text[0].selectionEnd,
beforeText = isTextAreaFocused ? currentValue.substring(0, start) : len,
afterText = isTextAreaFocused ? currentValue.substring(end) : len;
var insertedText = 'foo',
newValue = beforeText + insertedText + afterText + optionalNewline;
$text.val(newValue);
});
})
Problem
I believe that the button focuses before it has a chance to know if the textarea is focused. Is there a hook or way to handle the click event on the button such that I'll know (before it is focused) what is focused?
Off point: I'm using Ember as my framework. I'd really love to see a pure JS / jQuery solution, but I just wanted to place Ember on the table as well.
You'd have to use the mousedown event on the button, as it fires before the textarea loses focus.
By the time a click event fires, the mouse has been pressed down, and released, and the focus will have shifted to the button instead.
$(document).ready(function() {
$('button').on({
mousedown: function() {
var text = $('textarea').get(0),
currentValue = text.value,
isTextAreaFocused = text === document.activeElement,
insertedText = 'foo',
start = text.selectionStart,
end = text.selectionEnd,
beforeText = currentValue.substring(0, start) || "",
afterText = currentValue.substring(end) || "",
newValue = beforeText + insertedText + afterText;
text.value = isTextAreaFocused ? newValue : currentValue + insertedText + '\n';
$(this).data({'focus' : isTextAreaFocused, 'end' : end + insertedText.length});
},
mouseup: function() {
if ( $(this).data('focus') ) {
$('textarea').focus().get(0).setSelectionRange($(this).data('end'), $(this).data('end'));
}
}
});
});
textarea {
width: 20em;
height: 10em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea></textarea>
<button>Insert text</button>
I'm adding some code to a text area on button click, I'd like to put the cursor in a specific point in the text area.
e.g. cursor goes here on button click
Here is the code I have currently, any help would be great.
html
div
<textarea id="editor" class="html-text" spellcheck="false"></textarea>
jquery
$(".div").click(function() {
var caretPos = document.getElementById("editor").selectionStart;
var textAreaTxt = $("#editor").val();
var txtToAdd = '<div></div>';
$("#editor").val(textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos));
return false;
});
Use
$("#editor").focus();
to give focus back to the textarea, and then
$("#editor")[0].setSelectionRange(selectionStart, selectionEnd);
to place the cursor.
setSelectionRange
I have an input field where i append data at the cursor position.
after that, i set the selectionStart to the end of the field.
BUT, whenever i add something to the input (by button clicks), i only see the left part of it (until it reaches the right edge). everything more is there (i can select it with the mouse and scroll), but it doesn't automatically show the right edge.
how can i do that?
i want to add something to the input and jump right to the end of the string.
// add 2 digit number
$('button#2digit').on('click', function add2digit() {
addNumberToInput(10, 99);
});
function addNumberToInput(min, max) {
var problemInput = $('input#testProblem');
if (lastCharIsOperation() || problemInput.val().trim() < 1) { // if last char is an operation or first in string, just append the number
addAtCursor(randomNonPrime(min, max));
} else {
addAtCursor('+' + randomNonPrime(min, max));
}
}
function addAtCursor(toAdd) {
var problemInput = $('input#testProblem');
var oldText = problemInput.val();
var cursor = problemInput[0].selectionStart;
var pre = oldText.substring(0,cursor);
var post = oldText.substring(cursor, oldText.length);
//insert at cursor
problemInput.val(pre + toAdd + post);
//put cursor to end
problemInput[0].selectionStart = problemInput.val().length;
}
(it even skips back to the left on blur, i couldn't make a picture with the windows snipping tool, because i had to click it first)
From Set mouse focus and move cursor to end of input using jQuery.
var problemInput = $('input#testProblem');
problemInput.focus();
var t=problemInput.val();
problemInput.val('');
problemInput.val(t);
Here is the start of a full solution: https://jsfiddle.net/michaelgentry/vwm159pt/
This will still cause the scroll to jump back to the left on blur, but does what you are asking:
var elem = document.getElementById('myInput');
elem.focus();
elem.scrollLeft = elem.scrollWidth;
When I select some texts on the <textarea> using my mouse, how can I shuffle/scramble it by clicking on a button?
I've searched for something similar to what I want here on SO, and I saw some who use substring, selectionStart, and selectionEnd.
What I want is: when I select some texts with my mouse, it will be shuffled/scrambled when I click on a button, and the rest of the texts on the <textarea> that are not selected should remain untouched/intact.
I just want to perform an action on the selected texts.
It's more similar to a rich text editor like when you select on some texts, then click on bold button, the selected texts will become bold.
P.S.
It should be shuffled by individual characters.
EDIT:
Got it! I just needed to separate the selection string. My code works now. This is very helpful - https://stackoverflow.com/a/9605191/1101391
Unfortunately, IE 9 and below does not support selectionStart and selectionEnd properties on <input> and <textarea>. Here's the solution that worked for me - https://stackoverflow.com/a/9276457/1101391
You have access to the full text and know the substring where the selection starts and ends. Try something like this:
var txtArea = document.getElementById("foo");
var before = txtArea.value.substr(0, txtArea.selectionStart);
var selection = txtArea.value.substr(txtArea.selectionStart, txtArea.selectionEnd + 1);
var after = txtArea.value.substr(txtArea.selectionEnd, txtArea.value.length);
txtArea.value = before + scrambleThisString(selection) + after;
Suppose you name the textarea with ID content:
var textarea = document.getElementById('content');
var content = textarea.value;
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
var before = content.slice(0, start);
var after = content.slice(end);
var selected = content.substring(start, end);
selected = shuffleStringByMagic(selected);
textarea.value = before + selected + after;
I have this textarea that shows inputted text, but when the number of lines exceeds the size and width of the textarea, the user has to scroll down to see what they have last inputted.
I'd like the textarea to be set to the bottom everytime the enter button is pressed.
I've tried the following, but I can't get it to work:
function inputKeyDown(evt, input) {
if (evt.keyCode == 13) {
var textarea = document.getElementById("textarea");
textarea.value += "\n" + ">" + " " + input.value;
input.value = "";
return false;
}
var elem = document.getElementById('textarea');
elem.scrollTop = elem.scrollHeight;
}
and then I call the function keyDown in <input onKeyDown="return keyDown(event, this);" ...>
Any idea why no workie?
Try the following:
textarea.scrollTop = textarea.scrollHeight - textarea.clientHeight;
It depends on what sort of input you are looking at, but forcing the cursor back to the bottom could potentially be a serious usability problem. If you need a textarea that automatically expands, have a look at existing solutions such as this jQuery plugin
I'm not really sure if this is what you want but have a look this: http://jsfiddle.net/yV76p/
var textarea = document.getElementById("textarea");
textarea.onkeyup = function(evt) {
this.scrollTop = this.scrollHeight;
}