animate textarea content - javascript

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>

Related

How to make a certain part of textarea read-only

I have a text area and I dynamically add data to it and it works fine. What I wanted to achieve was after the data is appended that data cant be altered (edited) but after the last element of the data user can start typing on the textarea. I was thinking of maybe calculating the length of string data the set read-only to that part. How can I achieve this? Any help is appreciated. Thanks in advance.
For a visual example take a look at the terminal of this website: https://www.online-python.com/
function test() {
x = 'this is a string to be appended to text area'
document.getElementById("textArea").value = x;
}
<textarea id="textArea"></textarea>
<button onclick="test()">Append</button>
You can add a keydown event listener that checks whether the selectionStart is smaller than the length of the textarea's value minus the length of the string appended:
let x = 'this is a string to be appended to text area'
var hasAppended = false;
function test() {
hasAppended = true
document.getElementById("textArea").value = x;
}
textArea.addEventListener('keydown', function(e) {
if (hasAppended) {
if (this.selectionStart > this.value.length - x.length && this.selectionStart != this.value.length) {
e.preventDefault()
e.stopPropagation()
}
}
})
<textarea id="textArea"></textarea><button onclick="test()">Append</button>
It is not possible to selectively mark parts of a <textarea> read-only, however, a similar effect can be achieved with contenteditable elements:
function test() {
const x = 'this is a string to be appended to text area'
const span = document.createElement('span')
span.appendChild(document.createTextNode(x))
span.setAttribute('contenteditable', 'false')
document.getElementById("textArea").appendChild(span);
}
#textArea{
border: 1px solid black;
height: 50px;
}
<div id="textArea" contenteditable="true"></div>
<button onclick="test()">Append</button>
However, this will still allow the user to delete the read-only block, or write before it.
This almost works.
EDIT:
Improved it a bit by changing keydown to keyup.
Now there is no need for space at the end of the read-only text and CTRL+a and then backspace will make the text come back almost instantly.
Maybe you can improve on it.
window.onload = function() {
document.getElementById('textArea').addEventListener('keyup', function (e){
var readOnlyLength = parseInt(document.getElementById("textArea").getAttribute('data-readOnlyLength') );
var currentLength = parseInt(document.getElementById("textArea").value.length );
if (readOnlyLength >= currentLength ) {
document.getElementById("textArea").value = document.getElementById("textArea").getAttribute('data-readonly') ;
}
}, false);
};
function test() {
x = 'this is a string to be appended to text area'
document.getElementById("textArea").value = x;
document.getElementById("textArea").setAttribute('data-readonly' , x);
document.getElementById("textArea").setAttribute('data-readOnlyLength' , x.length);
}
<textarea id="textArea"></textarea>
<button onclick="test()">Append</button>

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>

Place cursor between 2 points in text area on button click

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

How to create a horizontal looping ticker in JQuery

I am working on a ticker that loops text within the body of a div. I can get it to move the text at a specified rate but I am having trouble figuring out how to get JQuery to loop the text. Once the contents in the div have reached the end, how do I loop it back while still showing rest of the contents from the tail?
Code:
var left = -500;
$(document).ready(function(e){
function tick() {
left++;
$(".ticker-text").css("margin-left", -left + "px");
setTimeout(tick, 16);
}
tick();
});
html:
<div class = "ticker-container">
<div class = "ticker-text">
start text text text text text text text text text text text text text text text
text text text text text text text text text text text text text text text text
text text text text text text text text text text text text text text text text end
</div>
</div>
http://jsfiddle.net/mxu4v/1/
Just reset the margin when it gets too far left:
var width = $('.ticker-text').width(),
containerwidth = $('.ticker-container').width(),
left = containerwidth;
$(document).ready(function(e){
function tick() {
if(--left < -width){
left = containerwidth;
}
$(".ticker-text").css("margin-left", left + "px");
setTimeout(tick, 16);
}
tick();
});
Note that the CSS must be changed so that .ticker-text assumes the width of its contents, and not 1000% as you specified:
.ticker-text {
height: 150%;
white-space:nowrap;
display:inline-block;
}
Here is a demonstration: http://jsfiddle.net/fHd4Z/
Just to flesh my comment out into an answer:
As above, I believe you'd be best of using one of the pre existing frameworks designed for this. In terms of a quick knock up of the feature, you could start with something like this: http://jsfiddle.net/B9ruA/
JS:
var tickerId="#tickerText";
function tickify(e) {
var text=$(e).text().split("");
var newText="";
for (var i=0;i<text.length;i++) {
newText+="<span class='tickerChar'>" + text[i] + "</span>";
}
$(e).html(newText);
}
tickify(tickerId);
function tick(){
$(tickerId + " span.tickerChar:first").hide("slide",{direction:"left"},50,function(){$(this).appendTo($(tickerId)).show("slide",{direction:"right"},50);});
}
setInterval(function(){tick()},200);
HTML:
<div id="tickerText"> woo, here is some text for ticking, text that ticks, ticky text to test with </div>
CSS:
div.ui-effects-wrapper {
display:inline;
}
notes:
I had to add some css to stop the animated characters being displayed as block (and thus on their own line). You would probably make the selector more specific to not screw with other animations on the page (if you have any).
Obviously this could do with some timing readjustments for smoothness sake - I couldn't be bothered doing the niggly trial and error work behind that but have fun (another reason to use a framework).
in my comment I mentioned the methods slideLeft and slideRight - they don't exist. my bad.

Find caret position in textarea in pixels [duplicate]

This question already has answers here:
How do I get the (x, y) pixel coordinates of the caret in text boxes?
(2 answers)
Closed 8 years ago.
I was wondering if it is possible to find the exact location of the caret inside a textarea in pixels in relation to the entire page. For instance, if I have typed This is text into my text box, I would like to know the pixels from the top left of the screen to the caret.
It would be in the form X: 200 Y: 100. This is so I can position a floating div. This needs to be done dynamically in javascript.
Thanks guys
This "raw code" works at least in IE.
Using the code you can put your <TEXTAREA> where ever you want in page, and the <DIV id="db"> will follow it. Even despite of the scrolling position of the page. You can fix the position of <DIV> by changing the literal numbers at d.style...6-statements.
<body>
<div id="db" style="position:absolute;left:-20px;top:-20px;border:1px solid red;">V</div>
<br><br><br>
<form id="props">
<textarea id="ta" style="width:200px;height:100px;" onkeyup="moveDiv();"></textarea>
</form>
<script>
<!--
var b=document.body;
var d=document.getElementById('db');
var a=document.getElementById('ta');
function moveDiv(){
var sel=document.selection;
var targ=sel.createRange();
d.style.top=a.offsetTop+a.clientTop-d.clientHeight-6;
d.style.left=targ.offsetLeft+b.scrollLeft-6;
return;
}
// -->
</script>
</body>
Positioning of the <DIV> is not quite exact, but gets better when using fixed-width font in <TEXTAREA>.
Here is a simple mix of ideas from Caret position in pixels in an input type text (not a textarea) , Caret position in textarea, in characters from the start and document.getElementById vs jQuery $() to get the caret position in jQuery for an <input> element. It works when clicking inside it, but not when moving the caret using the arrows or typing.
<input id="someid">
<span id="faux" style="display:none"></span><br/>
<script>
var inputter = $('#someid')[0];
var faux = $('#faux');
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
$("#someid").click( function( event ) {
caretpos = getCaret(inputter);
calcfaux = faux.text($(this).val().substring(0, caretpos));
fauxpos = calcfaux.outerWidth();
$("#getpx").text(fauxpos + " px");
});
</script>
Instead of var inputter = document.getElementById('someid') we use var inputter = $('#someid')[0];
Here is a FIDDLE.

Categories