characterCounter: Building a Feather-Weight jQuery Character Counting Plugin

Have you ever received a long unwanted or overflowing email through your contact form? If yes, then no wonder you have either deleted it permanently or ignored it. Isn’t it a good idea that we allow our users to enter only an exact number of characters to keep their message concise? Just like Twitter, we can show them the number of characters entered so far, maximum limit of characters and even color when the user is near to the permissible limit.

The whole purpose of building this plugin isn’t to restrict users, rather to allow them to convey their thoughts within a certain number of characters. I bet that genuine user will definitely convey their message easily within the minimum characters.

How to Build a Character Counter Plugin

Benefits of limited characters

Get ‘to the point’ message, in this fast moving spammy world, we don’t have enough time to go through each and every email and read them line by line. Wouldn’t it be time-saving for both sender and receiver to write and read a brief and relevant email quickly?

It does not mean the end of long messages, if you are thinking that it will be the death of long messages then boy you are wrong. It will encourage users to show their creative side to put their point in a limited fashion and I’m sure that after receiving the message, your mode of communication will be direct rather than again using that form. So, at this point in time, you can start exchanging long emails (or essay in it :D)

This tutorial assumes that you have experience in integrating jQuery plugin as well as some knowledge of JavaScript and jQuery.

Let’s dirty our hand in code mud

For the sake of simplicity, I have divided the plugin into three parts viz. Properties (what a web developer will add), error handling (as a plugin developer, how will you handle errors) and finally visual feedback (what a user will see if she exceeds or gets near to the permissible limit).

I will walk through in the same order as we have discussed above. So let’s dive into the properties part first.

Properties

As a plugin developer, you should make fellow developers lives easy by sticking with development standards and keep things simple from the property's names to their value.

As of now, we will talk about five important but essential properties. My plugin is available under the MIT license. Sorry for fancy word, let me simplify it. It means you can extend, break and play with my plugin and code without any restriction. So, this allows you to extend properties that may make sense in the future and distribute it. Let’s look at the role play by each property.

MaxLen [Mandatory]
As the name suggests, This mandatory property will be used to set maximum length. So, you can set to your own preference. You can take your lead from Twitter on your site by setting this to 160 characters.

warningLen [Mandatory]
This property will set visual feedback to numbers. So, if you have noticed on Twitter, it will show the remaining characters in rosewood color after 20 remaining characters (Ah, it mainly contains red color, what a fancy world). If you go to my personal website and check my contact form then you will notice that warningLen is 60 and MaxLen is 320 characters. Fair enough!

showMsg [Mandatory]
This is another mandatory property which is again useful for extra visual feedback. It basically allows you to set an alert message. It is directly associated with the next property i.e customMsg. If you set showMsg true, then you can set your custom alert message. Otherwise, it will take the default message.

Default message: "Oops, you are not allowed to enter more..."

customMsg [Optional]
Oh, finally an optional property. This will only work if you set showMsg true. So, now you have the power to add your own quirky message if you find my default message too boring.

separator [Optional]
This property will be used to separate the remaining characters with max length and purely for UI purposes. So, if you don’t set it then it will, by default use “|”, I call it a pipeline.

warningColor [Mandatory]
This last mandatory property will allow you to provide a color coded hint to your users. This is again for pure UI purposes. The nice thing is that you can use RGB, HEX or name of the color. It will work like a charm as far as jQuery supports that.

I hope you followed me so far. Let’s jump into the pure coding part. After reading the properties part, I know you are confident enough to put your hand more deeply into the mud (my bad, coding mud).

Error Handling

So I have divided this section into three parts from the variable declaration to sanity check to final execution.
So let’s set all the variables that we will get and use in this section from properties applied by the user in his document.

(function ($) {
    $.fn.characterCounter = function (options) {
 //variable declaration
        var maxLen = options.maxLen;
        var warningLen = options.warningLen;
        var showMsg = options.showMsg;
        var customMsg = options.customMsg;
        var separator= options.separator;
        var warningColor = options.warningColor;

We have used the same variable name as the property name to avoid confusion. So, now we have captured all the values into their relevant variables.

Allow users to enter only characters specified in the maxLen.

//set max Length to input box
        $(this).attr('maxlength', maxLen);

Check if the separator is not defined in the options, if not then use the default one.

     //if separator is not defined then use below one             
        if(!separator) 
                {
                    separator = "|";
                }

Now, we will check the property for any errors and as a good developer, will give them errors on the console and on the document too where the counter will appear. Word of caution: All the errors are written in the fancy language, so better you avoid them by error-free integration.

//checking properties of object
        if (!options.hasOwnProperty('maxLen')) {
            console.error("Defining maxLen is mandatory. Example: maxLen: 320");
            $('#counter').text("Oops, Something is missing. Get hint from console!");
        } else {
            $('#counter').html(maxLen + separator + maxLen);
        }

        if (!options.hasOwnProperty('warningLen')) {
            console.error("Defining warningLen is mandatory.This will give color coded hint to your user. Example: minLen: 60");
            $('#counter').text("Err! Something gone wrong. Please check your console.");
        }

        if (!options.hasOwnProperty('warningColor')) {
            console.error("Boy, Color is missing! Example: hexcode/rgba/name anything, you just name it!");
            $('#counter').text("Color is missing. See console for details.");
        }
        
        if (!options.hasOwnProperty('showMsg')) {
            console.error("It's very simple, just set showMsg property TRUE or FALSE. Example: False");
            $('#counter').text("Showing alert can be good idea to give extra information to user. See console brah!");

We have used hasOwnProperty to check whether the user has passed the mandatory property or not. According to MDN,

“The hasOwnProperty() method returns a boolean indicating whether the object has the specified property”

Now, we will put all our mandatory properties in an array and iterate it to check if they are present in our object options or not and if all are present then we will call keyup and update message length on every key up and calculate remaining characters by subtracting it from the max length.

Here I have used two IDs, #counter and #ccInvalid, So, you need to create one DIV with ID #counter. This DIV will show the character counter (only if you are lucky enough, otherwise you will get errors and instructions on the DIV).

     //procceed only if object has all properties 
        var propertyArray = ["maxLen", "warningLen", "showMsg", "warningColor"];
        if (propertyArray.every(function (x) {
                return x in options;
            })) {
            $(this).keyup(function () {
                var text_length = $(this).val().length;
                var text_remaining = maxLen - text_length;

  $('#counter').html("<span id='ccInvalid'>" + text_remaining + "</span>" + separator + maxLen);
       var msg = "Oops, you are not allowed to enter more...";
                if (text_remaining <= warningLen) {
                    $("#ccInvalid").css('color', warningColor);
                }
                if ((showMsg) && (text_remaining < 1)) {
                    if (options.hasOwnProperty('customMsg')) {
                        alert(customMsg);
                    } else {
                        alert(msg);
                    }
                }

            });
        }      

Visual Feedback

We have used three types of visual feedback and one from which one is for developers to see errors if they integrate the plugin in an ill manner and the other two (color coded hint and alert) for the user who visits your website and fills in the contact form.

Full Code

Plugin (Example – characterCounter.js)

(function ($) {
    $.fn.characterCounter = function (options) {
        //variable declarion
        var maxLen = options.maxLen;
        var warningLen = options.warningLen;
        var showMsg = options.showMsg;
        var customMsg = options.customMsg;
        var separator = options.separator;
        var warningColor = options.warningColor;
//set max Length to input box
        $(this).attr('maxlength', maxLen);
        //if separator is not defined then use below one             
        if(!separator) 
                {
                    separator = "|";
                }
        //checking properties of object
        if (!options.hasOwnProperty('maxLen')) {
            console.error("Defining maxLen is mandatory. Example: maxLen: 320");
            $('#counter').text("Oops, Something is missing. Get hint from console!");
        } else {
            $('#counter').html(maxLen + separator + maxLen);
        }

        if (!options.hasOwnProperty('warningLen')) {
            console.error("Defining warningLen is mandatory.This will give color coded hint to your user. Example: minLen: 60");
            $('#counter').text("Err! Something gone wrong. Please check your console.");
        }

        if (!options.hasOwnProperty('warningColor')) {
            console.error("Boy, Color is missing! Example: hexcode/rgba/name anything, you just name it!");
            $('#counter').text("Color is missing. See console for details.");
        }
        if (!options.hasOwnProperty('showMsg')) {
            console.error("It's very simple, just set showMsg property TRUE or FALSE. Example: False");
            $('#counter').text("Showing alert can be good idea to give extra information to user. See console brah!");
        } 
        //procceed only if object has all properties 
        var propertyArray = ["maxLen", "warningLen", "showMsg", "warningColor"];
        if (propertyArray.every(function (x) {
                return x in options;
            })) {
            $(this).keyup(function () {
                var text_length = $(this).val().length;
                var text_remaining = maxLen - text_length;

   $('#counter').html("<span id='ccInvalid'>" + text_remaining + "</span>" + separator + maxLen);
                var msg = "Oops, you are not allowed to enter more...";
                if (text_remaining <= warningLen) {
                    $("#ccInvalid").css('color', warningColor);
                }
                if ((showMsg) && (text_remaining < 1)) {
                    if (options.hasOwnProperty('customMsg')) {
                        alert(customMsg);
                    } else {
                        alert(msg);
                    }
                }

            });
        } 
    }
})(jQuery);

JS (Example – script.js)

$('#emailContents').characterCounter({
                        maxLen: 15,
                        warningLen: 5,
                        showMsg: true,
                        customMsg: "You have exceeded the permissible limit of characters..",
                        separator: "/",
                        warningColor: "#d50000",
                                        });

HTML (Example-index.html)

<textarea id="emailContents"></textarea>
<p id="counter">15/15</p>
 <!-- Javascripts -->
<script type="text/javascript" src="jquery-1.11.2.min.js"></script>
<script type="application/javascript" src="characterCounter.js"></script>
<script type="application/javascript" src="script.js"></script>

Conclusion

So the character counter can be very useful in many ways, a few of which we discussed in this tutorial. It can act as a first line of defense against spamming. Though, it is not foolproof to stop spamming, but it is definitely a good thing to integrate.

Did I mention that it is under the MIT license? So you can enjoy extending its functionality. I have tested it on Chrome and Firefox for both mobile and desktop.

You can download from here or check out the live demo.

I’m excited to hear your feedback on improving this plugin, or share the link to your contact page in the comments if you use it.

Opinions expressed in this article are those of the author and not necessarily those of Onextrapixel.