How to remember a position in a texarea? - javascript

I just want to remember always the last position in a textarea, but I fail always.
I've got this code:
//This function catch the position
(function ($, undefined) {
$.fn.getCursorPosition = function() {
var el = $(this).get(0);
var pos = 0;
if('selectionStart' in el) {
pos = el.selectionStart;
} else if('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
}
})(jQuery);
//Insert the text by clicking an icon
function insertar(texto) {
var div = $('textarea');
var text = div.val();
var pos = div.getCursorPosition();
text = text.substring(0,pos) + " " + texto + text.substring(pos);
div.val(text);
}
$('#icon').click(function(evt){ insertar(':icon:'); });
Well, if I write this:
"hello hello"
And I want to add this with the function:
"hi hi hello hello"
It give me this:
"hi hello hello hi."
I think the second time I execute the function, this forget the position and add the text at the end of the text.
PD: I'm adding text clicking on an image. I'm trying to do a quick reply fieldset for a forum.
Anyone knows where the problem is?
Here is my demo where you can see it: http://jsfiddle.net/ko295zpw/6/

One option would be to set a bool that determines whether or not you need to re-find the cursor position, then reset the bool to true every time the textarea is clicked and set it to false after you've found the position the first time after the user has clicked on the textarea. You'd need to move the declarations of both var pos and the bool to a scope outside the insertar function. So:
var encontrarPos = true;
var pos = 0;
function insertar(texto) {
var div = $('textarea');
var text = div.val();
if (encontrarPos) pos = div.getCursorPosition();
encontrarPos = false;
console.log(pos);
text = text.substring(0,pos) + texto + " " + text.substring(pos);
div.val(text);
}
$('textarea').click(function() {
encontrarPos = true;
});
And here's the updated Fiddle

Related

jQuery not able to set cursor inside newly added empty span

I am trying to set the cursor inside a empty span that I append, but it's not working. I did check out this question How to set the cursor inside a newly added empty span with Javascript (in a contenteditable div)?, But it didn't help me out
This is my code:
<script>
var app = angular.module('myApp',[]);
app.controller('editor',function($scope){
$scope.FontSize = function(start, end)
{
var size = [];
for (var i = start; i <= end; i++) {
size.push(i);
}
return size;
};
$scope.changeFont = function()
{
$("#content").append("<span id='one' style='font-size:"+$scope.kys_selected_font +"px' > </span>");
$("#one").focus();
};
});
</script>
I am able to set focus when i have text inside span, but not when it's empty.
Maybe you change code like this:
$scope.changeFont = function() {
var spanNode = $("<span id='one' style='font-size:" + $scope.kys_selected_font + "px' > </span>");
$("#content").append(spanNode);
spanNode.focus();
};

Get the value from a clicked button

I am creating a keyboard on my screen. Right now I am getting back the value of each letter when clicked through the function getLetter, but I need to grab that value and use it instead of prompt()[0]. So I want my input to be the actual letter ("A" or "B" or...). The problem is that I am not being able to put that value in the input variable. How do I do this?
abc = ['A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
$('#letters').text('');
for (i = 0; i < 26; i++) {
var div = $('<div>').css( 'cursor', 'pointer' );
div.html(abc[i]);
div.on('click', getLetter);
var newDiv = $('#letters').append(div);
}
$('body').append(newDiv);
function getLetter() {
$(this).text();
this.innerHTML = ' ';
this.style.cursor = 'default';
this.onclick = null;
}
while(!game.isOver()) {
var input = prompt()[0];
game.guess(input);
$('p').text(game.render());
}
You can move the contents of the while loop into the getLetter() function, and remove the while loop because it is useless now: you don't want to do anything until the user clicks a button.
function getLetter() {
var input=$(this).text();
this.innerHTML = ' ';
this.style.cursor = 'default';
this.onclick = null;
game.guess(input);
$('p').text(game.render());
}

Focus cursor after inserting text in textfield

I made the following function to insert a message (msg) into a textfield.
After inserting the text the cursor needs to be after the last character of the msg that was inputted. The textfield already contains some text.
When I insert the message the cursor gets focussed somewhere near the end of the msg but certainly not after the last character. It seems like some characters don't get counted by .length?
function insertAtCursor(msg) {
var textArea = document.getElementsByName("message")[0];
textArea.value = textArea.value.substr(0, textArea.selectionStart) + msg + textArea.value.substr(textArea.selectionEnd);
var endMsgPos = textArea.value.lastIndexOf(msg) + msg.length;
textArea.setSelectionRange(endMsgPos, endMsgPos);
}
There's no need for the textArea.value.lastIndexOf(msg).
function insertAtCursor(msg) {
var textArea = document.getElementsByName("message")[0];
var selStart = textArea.selectionStart, val = textArea.value;
textArea.value = val.slice(0, selStart) + msg +
val.slice(textArea.selectionEnd);
var endMsgPos = selStart + msg.length;
textArea.setSelectionRange(endMsgPos, endMsgPos);
}
First of all, you'll have an issue with IE 8 if you try to use textArea.selectionStart because it uses a different API.
Secondly lastIndexOf will behave strange in your code if the caret is at the begging of the string and somewhere at the end the value of the msg is present.
Try this:
function insertAtCursor(msg) {
var e = document.getElementsByName('message')[0],
length = msg.length, val = e.value;
/* mozilla / dom 3.0 */
if ('selectionStart' in e){
var partial = val.slice(0, e.selectionStart) + msg;
e.value = partial + val.slice(e.selectionEnd);
var end = partial.length;
e.setSelectionRange(end, end);
}
/* exploder */
if (document.selection){
e.focus();
document.selection.createRange().text = msg;
}
}
The demo is here : http://jsbin.com/UnOBUbU/6

If text is selected, and dropdown option is clicked, change color of selected text

I want to make a text editor, and when you select some text in the text area, then click an option from the drop down, the selected text from the text area changes color. Unfortunately I don't know how to do this because when I try to access the drop down, the selection from the text area disappears.
jsFiddle :: http://jsfiddle.net/MatthewKosloski/a77sM/
function GetSelectedText () {
if (window.getSelection) { // all browsers, except IE before version 9
var range = window.getSelection ();
var selection = range.toString();
alert(selection);
}
}
I've been playing around with trying to change color of highlighted content within the textarea, but it seems that you cannot change the color of text within a textarea. An alternative, as has been suggested before, is to create an editable div that acts as a rich textbox. You can set the contentEditable property on the div to true in order for this to work. Here is my jsfiddle if you want to play around with it.
And here is my JS code. I changed a couple things on the HTML too so check out the jsfiddle for the full code.
function GetSelectedText (origtext, seltext, tcolor) {
//alert(origtext + ", " + seltext + ", " + tcolor);
var divcontent = document.getElementById('sec');
var spanTag = document.createElement("span");
var selIndex = origtext.indexOf(seltext);
var selLength = seltext.length;
//split the text to insert a span with a new color
var fpart = origtext.substr(0, selIndex);
var spart = origtext.substr(selIndex + selLength);
//alert(fpart + ", " + spart);
// add the text that was highlighted and set the color
spanTag.appendChild(document.createTextNode(seltext));
spanTag.style.color = tcolor;
//remove all the children of the div
while(divcontent.hasChildNodes()){
divcontent.removeChild(divcontent.lastChild);
}
//append the original text with the highlighted part
divcontent.appendChild(document.createTextNode(fpart));
divcontent.appendChild(spanTag);
divcontent.appendChild(document.createTextNode(spart));
}
// this function was found at http://stackoverflow.com/questions/275761/how-to-get-selected-text-from-textbox-control-with-javascript
function getTextFieldSelection() {
var textComponent = document.getElementById('content');
var selectElem = document.getElementById("myselect");
var selectedText;
// IE version
if (document.selection != undefined)
{
textComponent.focus();
var sel = document.selection.createRange();
selectedText = sel.text;
}
// Mozilla version
else if (textComponent.selectionStart != undefined)
{
var startPos = textComponent.selectionStart;
var endPos = textComponent.selectionEnd;
selectedText = textComponent.value.substring(startPos, endPos)
}
//alert("You selected: " + selectedText);
selectElem.onchange = GetSelectedText(textComponent.value, selectedText,selectElem.options[selectElem.selectedIndex].text.toLowerCase());
}
var content = document.getElementById("content");
var selectElem = document.getElementById("myselect");
selectElem.onfocus = function (e) { getTextFieldSelection(); };
The problem is when you click the select element it steals focus from textarea.
You have to give back the focus to textarea element, here is a working example (at least in chrome):
var color = document.getElementById("color"), // this is the select element
content = document.getElementById("content");
color.onfocus = function (){ content.focus(); };

Setting a Range for a Textarea based on User Input

I have a textarea and I'm trying to check if someone enters {{link that I can have a modal pop up to let them complete some information.
What I have now is that if someone enters the letter k, it will go back 6 characters and then determine if the text matches {{link
But I'm having a problem in setting setting the start and end points for the range. I think that the problem is with identifying the node, but I'm not sure.
Mainly when someone enters a the letter "k", I'm just trying to go back to check if they had typed: {{link and if they did, it would launch a modal.
This is what I have that isn't working at the part where I'm trying to set the range and get the selection.
$(document).on('keyup', 'textarea', function(e) {
if (e.keyCode == 75) {
var end = $('textarea').getCaretPosition();
var start = end - 6;
var node = $(this).get(0);
var range = document.createRange();
range.setStart(node, start);
range.setEnd(node, end);
var selection = range.toString();
if( selection == '{{link' ){
// we'll launch a modal here
}
}
});
$.fn.getCaretPosition = function() {
var el = $(this).get(0);
var pos = 0;
if ('selectionStart' in el) {
pos = el.selectionStart;
} else if ('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
}
This generates the error: Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1 at range.setStart(node, start);
Not sure if this is what you mean http://jsfiddle.net/sailorob/J6PVJ/

Categories