0👍
The keydown
event fires before the value in the field has been updated. As such your JS is displaying the character calculation from the previous keypress. keyup
is the better choice of the two.
However, that being said, you should use the input
event instead as it covers all cases where the value of the field changes which keydown
/keyup
don’t – for example copy & paste using the mouse.
Also note that jQuery 1.5 is massively outdated – over 10 years old in fact. You should be using the latest version which at time of answering is 3.6. In addition using onX
event attributes is no longer good practice. Look to attach your event handlers unobtrusively without including any JS in the HTML. As you’re using jQuery already you can use the on()
method to do that
With all that said, try this:
jQuery($ => {
const $charNum = $('#charNum');
$('#field').on('input', e => {
let len = e.target.value.length;
$charNum.text(800 - len);
}).trigger('input');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id='id_text' class="control-group">
<label for="id_text" class="control-label">Text</label>
<div class="controls">
<label for="field"></label>
<textarea id="field" maxlength="800"></textarea>
</div>
<span>Char Left:</span> <span id="charNum"> </span>
</div>
1👍
counting the characters from a textarea you have 2 ways in JavaScript
- to count characters with the spaces between words, you just have to get the content of your texarea, and mesure the "length". Remember : "The String prototype object has a "length" property whose initial value is 0 "
//injecting "hello world" (10 characters and 1 space) into the DOM
let newDiv = document.createElement("div")
let newContent = document.createTextNode(`hello world`)
newDiv.setAttribute("id", "Div1")
newDiv.appendChild(newContent)
document.body.appendChild(newDiv)
let str = document.getElementById("Div1").innerHTML
//counting the number of characters injected
alert(`LENGHT = ` + `${str.length}`); // HERE THE PROPERTY LENGTH ..
- here counting characters WITHOUT the spaces between words " :
//injecting "hello world" (10 characters and 1 space) into the DOM
let newDiv = document.createElement("div")
let newContent = document.createTextNode(`hello world`)
newDiv.setAttribute("id", "Div1")
newDiv.appendChild(newContent)
document.body.appendChild(newDiv)
let str = document.getElementById("Div1").innerHTML
//first you split the content using String.prototype.split ( separator, limit ) then concatenate the array obtained by the split without spaces using : Array.prototype.join ( separator )
alert(str.split(' ').join('').length)
UPDATE :
About performance following the idea of @jallmer to use the method replace + REGEX
//injecting "hello world" (10 characters and 1 space) into the DOM
let newDiv = document.createElement("div")
let newContent = document.createTextNode(`hello world`)
newDiv.setAttribute("id", "Div1")
newDiv.appendChild(newContent)
document.body.appendChild(newDiv)
//testing algorithms perfs
let str1 = document.getElementById("Div1").innerHTML
let str2= document.getElementById("Div1").innerHTML
//testing algorithm 1
console.log(`str1 = ${str1}`)
const t0 = performance.now();
console.log(str1.split(' ').join('').length)
const t1 = performance.now()
console.log(`algorithm 1 took ${t1 - t0} milliseconds.`);
//testing method 2
console.log(`str2 = ${str2}`)
const t2 = performance.now();
console.log(str2.replace(/\s/g, '').length)
const t3 = performance.now()
console.log(`algorithm 2 took ${t3 - t2} milliseconds.`);
and curiously the results are different on my chrome dev tools (Chrome for Gnu/Linux, version 90.0.4430.93 (Official Build) (64-bit)). Something to inspect :
- [Answered ]-Django Signal request_finished
- [Answered ]-Python django, when creating an registering form how to get this .get method working?