I've searched the jQuery docs and here and can't find an answer to my exact problem...
With a DRY spirit, I want to use javascript to add a character object countdown helper to any textarea element with maxlength and aria-describedby attributes.
Obviously I also need to use javascript to monitor keyup events to update the counter. I'm using jQuery 3.6.0. However, I can't seem to get the countdown method to recognize the newly-added "helper" div element. Here's what I have so far:
$(document).ready(function () {
// "characters remaining" countdown
function textCounter(field) {
var charLimit = field.attr("maxlength");
console.log("charLimit=" + charLimit);
// hack to *double-count* '\r\n' (client/DB discrepency)
var numLines = (field.val().match(/\n/g) || []).length;
var charLength = field.val().length + numLines;
console.log("charLength=" + charLength);
var charDiff = charLimit - charLength;
console.log("charDiff=" + charDiff);
if (charLength > charLimit - numLines)
field.val(field.val().substring(0, charLimit - numLines));
var count = $("#" + field.attr("aria-describedby") + " .count");
console.log(count.html());
count.html(Math.max(0, charDiff));
}
// add countdown helper div
$("textarea[maxlength]").each(function (e) {
var helpID = "#" + $(this).attr("aria-describedby");
var helpDiv = $('<div id="' + helpID + '"><span class="count"></span> characters left.</div>')
$(this).after(helpDiv);
textCounter($(this));
})
// update counter on keyup events
$("textarea[maxlength]").keyup(function () { textCounter($(this)); })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea maxlength="2000" aria-describedby="content-help" id="content" name="content"></textarea>
Run code snippet
Expand snippet
I can confirm that:
- The helper div element is getting added
- Via the console.log statements, the textCounter() method is getting called, but the count object resolves to undefined (even though it is clearly there), and
- If the element is hardcoded in HTML (i.e., not dynamically added) the counter works as expected.
Other searches suggest that .delegate() or .on() are part of the answer, but everything I've tried has the exact same behavior as above. :( Every other Q/A I've come across is, for example, binding a click/hover event to the newly-added element, but here it's the textarea that needs monitoring (not the new helper element, although it will be updated), if that makes sense...
Note that I want the solution to work on pages that have multiple textareas, each with potentially different maxlength attributes.
Any thoughts how to accomplish this?