We have a legacy app using jQuery Steps for its wizard. Now we'd like to add some word count/line count alert inside the wizard input area.
Our textarea defined:
<textarea
id="customized-text"
data-toggle="tooltip"
data-placement="top"
maxlength="80"
data-line-max="10"
data-maxlength-message-selector="#customized_text_length_display"
data-length-limit-message="Max number of lines reached"
></textarea>
<span id="customized_text_length_display" class='length-limit'>0/620
</span>
We'd like to count via keydown/keyup action fireoff. But jQuery Steps rewrite the DOM when it renders, so we can't bind an event to the actual element, it has to be bound on document
.
$(document).on("keydown", "textarea.with-line-limit",function(e){
// calculate the lines and disable input if it reaches predefined max number of lines.
});
But when we bind the keydown event to the word count, it's always one word behind. After the first word shown in input area, word count is still 0. After 2nd word typed, word count shown as 1. The reason is that counting action is bound to keydown
and a word doesn't show up on screen until key up action. So when word count triggered by keydown
action, there's no word on screen yet and count is 0.
To bind word count with keyup
,
$(document).on("keyup", "textarea.with-line-limit",function(e){
//does word count here.
});
However, this keyup event was never fired off when words were typed inside the textarea. Our guess is because jQuery Steps modifies DOM, it has some mysterious behavior. We found two solutions.
Solution 1
Although we can't bind the event directly to the actual element, we could define a global function. That function binds keyup
to an element from the page. Then at jQuery init step, call the function to make the binding happen.
window.wordCount = function() {
$("#customized-text").on("keyup", function(){
// does word count here
});
Solution 2
Since document can be bound at keydown
event, we use that to find keyup
.
$(document).on("keydown", "textarea[maxlength], input[maxlength]", function(e){
$(this).one("keyup", function(e){
// does word count here
});
});
Both of them work. But both seem hacky. If you know a better way of doing this, please let me know!