Place cursor between 2 points in text area on button click - javascript

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

Related

Get cursor position in contentEditable div, open pop up, then insert new html at cursor position

I am building a very simple rich text editor using a content editable div. If a user clicks inside the div, then clicks a link manager button, and enters some link text and address into a modal popop, then clicks OK, I want to build a hyperlink and insert it at the previously selected cursor position in the div. I have tried capturing the selected range and caching it (via div onblur event), then inserting my new content into that range but it always dumps the new content at the start of the content editable area, eg
var preCaretRange = null;
function CacheRange() {
sel = win.getSelection();
if (sel.rangeCount > 0) {
preCaretRange = sel.getRangeAt(0);
}
}
function CreateLink() {
// get user input
var linkname = "blah";
var linkaddr = "http://blah.com";
var frag = "<a href=\"" + linkaddr + "\" target='_new'>" + linkname + "</a>";
var rtDiv = document.getElementById("myDiv");
rtDiv.focus();
if (preCaretRange == null) {
rtDiv.innerHTML += " " + frag;
} else {
preCaretRange.insertNode($(frag)[0]);
}
}
<div id=mydiv contenteditable=true onblur="CacheRange(this)"></div>
<input type='button' onclick='CreateLink()' />
The new html tag gets inserted at the start of the content, not the cursor position. I have followed numerous examples of how to do this but my range won't dump its new contents into the correct place. Hopefully someone can spot the issue.
For those interested, I uncovered an IE quirk. If you click on a non-button element (eg, and tag seyled with font-awesome), and try to do what I am trying to do, ie, cache the selected range, then put a new element back over the top of it, in IE it inserts the new element over the thing you last clicked. If you use a button, however, it works fine. Go figure. No issues in Chrome.

How to change the background color of the modified text in a text area

I want to know how to change the background color or may be color of the text that was modified in a textarea.
Like suppose, consider a textarea with a pre-defined value as "Hello World".
Now if you try to change the text inside the textarea to "Hello Universe", it should show Universe highlighted (may be background color change, or color change or make it bold, anything.
I just want to get the modified text to be highlighted so it is visible what was changed.
Highlighting is possible if you make the textarea partially transparent and then had a div behind it where you can clone the content and put span tags around the changed values. The hard part is in figuring out how to diff the string. For an example of highlight certain parts of text "in the text area" see this fiddle:
https://jsfiddle.net/mcgraphix/tn0ahcfx/
<div class="container">
<div id="highlighter"></div>
<textarea id="editor" onkeyup="updateHighlight()"
value="This is some text in the editor"></textarea>
</div>
JS
function updateHighlight() {
//calculate index of changes
//assume chars 1-10 are different //see my comment for how to calculate what to highlight
var content = document.getElementById('editor').value;
var highlighted = '';
var i = 0;
while (i < content.length) {
if (i === 1) {
highlighted += '<span class="highlighted">';
} else if (i > 10) {
highlighted += '</span>'
}
highlighted += content.charAt(i);
i++;
}
document.getElementById('highlighter').innerHTML = highlighted;
}
Basically, as you type the text in the text area is parsed and as text is identified as being in need of highlight, a span tag is wrapped around it. After parsing the text, the copy with the spans is put inside the div that is behind the textarea. With the right css you can hide the text in that div and just put a background color such that it looks highlighted. The fiddle gives you the basic idea but you would have to account for the user resizing the text area as you need to make sure the text area and the "highlighter" behind it are aligned.
The hard part is figuring out what to highlight. such that you don't highlight every character after the first change. Take a look at Levenshtein distance algorithm for determining which characters you need to highlight when comparing two strings.
Keep old value in variable.
Split the value using delimiter as space
Check indexOf new value after spitting by space
Use Array#indexOf to listen the change in value!
Most important point, you can not apply style over characters in textarea. Example given below has a demonstration in div element considering value from textarea
var input = $('textarea');
var div = $('div');
var oldVal = input.val();
var oldArr = oldVal.split(' ');
input.on('input', function() {
var newVal = this.value;
var html = [];
newVal.split(' ').forEach(function(el) {
if (oldArr.indexOf(el) === -1) {
html.push('<span style="color:green">' + el + '</span>');
} else {
html.push('<span>' + el + '</span>');
}
});
div.html(html.join(' '));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<textarea>Hello World</textarea>
<div></div>

Clicking outside of textarea loses caret position

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.

Append HTML Tag Into Codemirror and Center Cursor Location

Fiddle - http://liveweave.com/kzBlq3
I'm trying to add custom html tags into CodeMirror and focus the cursor into the center of these tags.
Here's an example of how it'd be done for a textarea.
// Mirror Codemirror Code to Textarea
$(".code").val( editor.getValue() ).on('keyup change', function() {
editor.setValue( $(this).val() );
});
// Add center code
$(".bold").click(function() {
// For a regular textarea & center cursor
var start = $('.code').get(0).selectionStart;
$('.code').val($('.code').val().substring(0, start) + "<strong></strong>" + $('.code').val().substring($('.code').get(0).selectionEnd));
$('.code').get(0).selectionStart = $('.code').get(0).selectionEnd = start + 8;
$('.code').focus();
return false;
});
The lines and locations will always be different so I have to grab it's location first before I add and move it aside the added characters as I did with the textarea demo.
However I don't want to use a blank textarea. I want to use Codemirror.
I can add the html tag without a problem, but getting the cursor location inside of the appended tag is where I'm having trouble.
editor.replaceRange("<strong></strong>", editor.getCursor());
Add the following code to move cursor to center of tag. Also I updated your code, Please use the below link for accessing it
http://liveweave.com/LLq9GS
$(".bold").click(function() {
// For codemirror & center cursor
editor.replaceRange("<strong></strong>", editor.getCursor());
editor.focus();
var str="</strong>";
var mynum=str.length;
var start_cursor = editor.getCursor(); //I need to get the cursor position
console.log(start_cursor); //Cursor position
var cursorLine = start_cursor.line;
var cursorCh = start_cursor.ch;
//Code to move cursor back [x] amount of spaces. [x] is the data-val value.
editor.setCursor({line: cursorLine , ch : cursorCh -mynum });

animate textarea content

I have a paragragh of user entered text in a textarea.
line1
line2
line3
intially all text would be black
when a button is pressed
each line's color changes to red gradually (2 sec each line)
can this be done with only jquery?
EDIT: Sorry again mate didn't realize you said TEXTAREA this time.
No it cannot be done. However you could do this:
When the button is pressed hide the textarea and display a div in it's place with the content from the textarea. Perform the animation on that instead. Of course it wouldn't be editable anymore but as I don't know what you are trying to achieve this could be a work-around.
Here's an example of above.
<textarea id="ta"></textarea>
<div id="ta_div" style="display:none;"></div>
<br/><input type="button" id="go" value="Go"/>
<script>
$("#go").click(function()
{
var text = document.getElementById("ta").value;
text = "<p>" + text.replace( /\n/g, "</p><p>" ) + "</p>";
$("#ta_div").html( text );
$("#ta").hide();
$("#ta_div").show();
var i = -1;
var arr = $("#ta_div p");
(function(){
if(arr[++i])
$(arr[i]).animate({ color: "#ff0000" }, 2000, "linear", arguments.callee)
})();
});
</script>

Categories