Textarea onchange detection
JavascriptJavascript Problem Overview
How do I detect change event on textarea using javascript?
I'm trying to detect how many characters left is available as you type.
I tried using the onchange event, but that seems to only kick in when focus is out.
Javascript Solutions
Solution 1 - Javascript
The best way to do this, cross-browser: use a combination of the input
and onpropertychange
events, like so:
var area = container.querySelector('textarea');
if (area.addEventListener) {
area.addEventListener('input', function() {
// event handling code for sane browsers
}, false);
} else if (area.attachEvent) {
area.attachEvent('onpropertychange', function() {
// IE-specific event handling code
});
}
The input
event takes care of IE9+, FF, Chrome, Opera and Safari, and onpropertychange
takes care of IE8 (it also works with IE6 and 7, but there are some bugs).
The advantage of using input
and onpropertychange
is that they don't fire unnecessarily (like when pressing the Ctrl
or Shift
keys); so if you wish to run a relatively expensive operation when the textarea contents change, this is the way to go.
Now IE, as always, does a half-assed job of supporting this: neither input
nor onpropertychange
fires in IE when characters are deleted from the textarea. So if you need to handle deletion of characters in IE, use keypress
(as opposed to using keyup
/ keydown
, because they fire only once even if the user presses and holds a key down).
Source: http://www.alistapart.com/articles/expanding-text-areas-made-elegant/
EDIT: It seems even the above solution is not perfect, as rightly pointed out in the comments: the presence of the addEventListener
property on the textarea does not imply you're working with a sane browser; similarly the presence of the attachEvent
property does not imply IE. If you want your code to be really air-tight, you should consider changing that. See Tim Down's comment for pointers.
Solution 2 - Javascript
You will need to use onkeyup
and onchange
for this. The onchange will prevent context-menu pasting, and the onkeyup will fire for every keystroke.
See my answer on How to impose maxlength on textArea for a code sample.
Solution 3 - Javascript
- For Google-Chrome, oninput will be sufficient (Tested on Windows 7 with Version 22.0.1229.94 m).
- For IE 9, oninput will catch everything except cut via contextmenu and backspace.
- For IE 8, onpropertychange is required to catch pasting in addition to oninput.
- For IE 9 + 8, onkeyup is required to catch backspace.
- For IE 9 + 8, onmousemove is the only way I found to catch cutting via contextmenu
Not tested on Firefox.
var isIE = /*@cc_on!@*/false; // Note: This line breaks closure compiler...
function SuperDuperFunction() {
// DoSomething
}
function SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally() {
if(isIE) // For Chrome, oninput works as expected
SuperDuperFunction();
}
<textarea id="taSource"
class="taSplitted"
rows="4"
cols="50"
oninput="SuperDuperFunction();"
onpropertychange="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
onmousemove="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
onkeyup="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();">
Test
</textarea>
Solution 4 - Javascript
I know this isn't exactly your question but I thought this might be useful. For certain applications it is nice to have the change function fire not every single time a key is pressed. This can be achieved with something like this:
var text = document.createElement('textarea');
text.rows = 10;
text.cols = 40;
document.body.appendChild(text);
text.onkeyup = function(){
var callcount = 0;
var action = function(){
alert('changed');
}
var delayAction = function(action, time){
var expectcallcount = callcount;
var delay = function(){
if(callcount == expectcallcount){
action();
}
}
setTimeout(delay, time);
}
return function(eventtrigger){
++callcount;
delayAction(action, 1200);
}
}();
This works by testing if a more recent event has fired within a certain delay period. Good luck!
Solution 5 - Javascript
I know this question was specific to JavaScript, however, there seems to be no good, clean way to ALWAYS detect when a textarea changes in all current browsers. I've learned jquery has taken care of it for us. It even handles contextual menu changes to text areas. The same syntax is used regardless of input type.
$('div.lawyerList').on('change','textarea',function(){
// Change occurred so count chars...
});
or
$('textarea').on('change',function(){
// Change occurred so count chars...
});
Solution 6 - Javascript
You can listen to event on change of textarea and do the changes as per you want. Here is one example.
const textArea = document.getElementById('my_text_area');
textArea.addEventListener('input', () => {
var textLn = textArea.value.length;
if(textLn >= 100) {
textArea.style.fontSize = '10pt';
}
})
<html>
<textarea id='my_text_area' rows="4" cols="50" style="font-size:40pt">
This text will change font after 100.
Solution 7 - Javascript
Keyup should suffice if paired with HTML5 input validation/pattern attribute. So, create a pattern (regex) to validate the input and act upon the .checkValidity() status. Something like below could work. In your case you would want a regex to match length. My solution is in use / demo-able online here.
<input type="text" pattern="[a-zA-Z]+" id="my-input">
var myInput = document.getElementById = "my-input";
myInput.addEventListener("keyup", function(){
if(!this.checkValidity() || !this.value){
submitButton.disabled = true;
} else {
submitButton.disabled = false;
}
});
Solution 8 - Javascript
Code I have used for IE 11 without jquery and just for a single textarea:
Javascript:
// Impede que o comentário tenha mais de num_max caracteres
var internalChange= 0; // important, prevent reenter
function limit_char(max)
{
if (internalChange == 1)
{
internalChange= 0;
return;
}
internalChange= 1;
// <form> and <textarea> are the ID's of your form and textarea objects
<form>.<textarea>.value= <form>.<textarea>.value.substring(0,max);
}
and html:
<TEXTAREA onpropertychange='limit_char(5)' ...
Solution 9 - Javascript
Try this one. It's simple, and since it's 2016 I am sure it will work on most browsers.
<textarea id="text" cols="50" rows="5" onkeyup="check()" maxlength="15"></textarea>
<div><span id="spn"></span> characters left</div>
function check(){
var string = document.getElementById("url").value
var left = 15 - string.length;
document.getElementById("spn").innerHTML = left;
}
Solution 10 - Javascript
The best thing that you can do is to set a function to be called on a given amount of time and this function to check the contents of your textarea.
self.setInterval('checkTextAreaValue()', 50);