Simple jQuery for character counts on an input box

A quick tip here on adding a simple character count element to accompany an HTML input.

Imagine you’ve added the “maxlength” attribute to a text input box and now want to provide some real-time feedback to your users as they fill out that input indicating the amount of characters remaining. In my experience, there’s 4 key JS events you’ll want to bind to for maximum likelihood that your character counter updates on all changes: keyup, focusout, paste & cut.

Normally, a simple jQuery $.on() would be all you need, something like this:

$('#MyText').on('keyup focusout paste cut',function(){
  $('#CharCounter').text(255 - $(this).val().length);

Try that though & you’ll see a small issue; the paste & cut events aren’t updating correctly. They actually are running, but the reason the counter seems off is that the timing of the events causes the bound function to run before the value of the input is actually changed; they literally fire so fast, the result of the cut or paste hasn’t actually changed the value if the input when it fires.

Fortunately, this is readily addresses by adding a small (even 10ms) setTimeout() function call – and by checking the event.type that triggers the call, you can conditional only use the setTimeout() for those two events.

Not content to stop there though, I wanted a more flexible, reusable solution. Consider the below which then adds a few key features:

  • The aforementioned conditional check for the firing event has been added
  • Initialized via input class so that it can be easily reused within a given form
  • The “maxlength” to substract the char count from is pulled from the input itself instead of hardcoded in the function
  • A custom “data-CountElem” attribute is added to the input markup to identify (by ID) the element you want to write/update the char count to

Check out the jsFiddle here – code below:

$('.UseCharCount').on('keyup focusout paste cut',function(event){
  var self = $(this);
  if(event.type == 'keyup' || event.type == 'focusout')
    $('#' + self.attr('data-CountElem')).text(self.attr('maxlength') - self.val().length);
  else if(event.type == 'paste' || event.type == 'cut') {
      $('#' + self.attr('data-CountElem')).text(self.attr('maxlength') - self.val().length);

Comments are closed.