Limiting character count with TinyMCE

tinymce-limit-character-count

Tame TinyMCE and character limits!

As a general rule of thumb I don’t like to bore my readers with ‘technical tips’ but I felt I wanted to share this particular technique, mostly because the suggested solutions out there seemed a confused and complicated mess, and partly because I feel like I’m always ‘taking’ from the internet community and not doing a lot of reciprocating so hopefully this can reduce my ‘knowledge debt’.

Limiting the number of characters in a form field is normally straightforward; you simply add a maxlength attribute to the field. But when you throw in the TinyMCE plugin 3.3.6 (which is a fantastic inline editor for textarea fields) it goes pear-shaped. TinyMCE takes over and ignores any maxlength attributes or javascript actions on the field. The solution? Well I’m glad you asked, here it is:

Update your TinyMCE script to include a built-in function, the getContent line shown below. This retrieves (I remove any HTML tags before I get the count) the number of characters in the editor whenever a key is pressed.

tinyMCE.init({
theme : "advanced",
mode : "textareas",
skin : "o2k7",
skin_variant : "silver",
plugins : "spellchecker,fullscreen",
theme_advanced_buttons3_add : "spellchecker,fullscreen",
theme_advanced_toolbar_location : "top",
theme_advanced_disable : "image,styleselect,anchor,sub,sup,hr,visualaid,help",
theme_advanced_toolbar_align : "left",
theme_advanced_layout_manager : "SimpleLayout",
fullscreen_new_window : true,
fullscreen_settings : {
theme_advanced_path_location : "top"
},
theme_advanced_buttons1 : "bold,italic,underline,separator,bullist,numlist,separator,cut,copy,paste,separator,
undo,redo,separator,link,unlink,cleanup",
theme_advanced_buttons2 : "formatselect,styleselect,spellchecker,separator,fullscreen",
theme_advanced_buttons3 : "",
content_css : "style.css",
setup : function (ed) {
ed.onKeyDown.add(
function (ed, evt) {
document.form1.deslen.value = tinyMCE.activeEditor.getContent().replace(/<[^>]+>/g, '').length;
}
);
}
});

You’ll notice in the code above I refer to a field on the form called deslen. This field is read-only and displays the current number of characters in the editor.

< input id=”deslen” name=”deslen” readonly size=”10″ type=”input” > characters (max 2000)

Nothing startling so far. Here's the part where you prevent the form submitting if the user has exceeded the stated number of characters. Hopefully you're already using jQuery validation on your form. The trick is to perform the validation on the field shown above, not the actual textarea field. You can use the built-in min and max validation routines to ensure that (a) the field has been completed and (b) the character limit hasn't been exceeded. Below is an excerpt from the jQuery validation script (customise to suit your own particular limits):

$(document).ready(function() {
// validate form on keyup and submit
$("#form1").validate({
rules: {
deslen: {
min: 2,
max: 2000
}
},
messages: {
deslen: {
min: " Please enter a description",
max: " Description must not be longer than 2000 characters"
},
}
});
});

Whammy! Works a treat as shown in the screenshot above. In my opinion this is the nicest solution for the user. It does what it's meant to do without being obtrusive. Feel free to comment if it's not working for you or I've missed something.

Posted in Technical Tips and tagged , , .

11 Comments

  1. There’s only one thing (that i noticed) missing on your code: you must add a line with a function like the one you for the onkeydown event but for the onkeyup event. if you don’t the char count will be all messed up if you, e.g., select a part of the written text and delete it. the char count will hit +1 instead of doing the opposite.

    However, the rest of the code is really what i was looking for. nice job.

  2. Hi, I´m sorry for my english…

    Is better to include this code:

    setup : function (ed) {
    ed.onKeyUp.add(
    function (ed, evt) {
    document.form1.deslen.value = tinyMCE.activeEditor.getContent().replace(/]+>/g, ”).length;
    }
    );
    }

    if you want to see the number of characters put:

    setup : function (ed) {
    ed.onKeyUp.add(
    function (ed, evt) {
    alert(tinyMCE.activeEditor.getContent().replace(/]+>/g, ”).length);
    }
    );
    }

    with the onKeyUp function instead of the onKeyDown funtion.

  3. Hi
    This looks cool

    Thanks for the script – How about using this for multiple instances?
    Is there any way for that?

    Thank You
    Sathish

  4. For getting out all the Htmlentities just add this:

    replace(/\&[^;]+;/g, ‘#’)

    and make it to this:

    tinyMCE.activeEditor.getContent().replace(/]+>/g, ”).replace(/\&[^;]+;/g, ‘#’).length;

  5. in most cases there should be no issues with multiple instances that are identified correctly. just make sure you’re using the latest version of jquery.

  6. I am getting error while applying this.

    Please guide where to write this code. I am using joomla and I am wirting this code in tinyMce.php file in lugin.

    tinyMCE.init({
    theme : “advanced”,
    mode : “textareas”,
    skin : “o2k7″,
    skin_variant : “silver”,
    plugins : “spellchecker,fullscreen”,
    theme_advanced_buttons3_add : “spellchecker,fullscreen”,
    theme_advanced_toolbar_location : “top”,
    theme_advanced_disable : “image,styleselect,anchor,sub,sup,hr,visualaid,help”,
    theme_advanced_toolbar_align : “left”,
    theme_advanced_layout_manager : “SimpleLayout”,
    fullscreen_new_window : true,
    fullscreen_settings : {
    theme_advanced_path_location : “top”
    },
    theme_advanced_buttons1 : “bold,italic,underline,separator,bullist,numlist,separator,cut,copy,paste,separator,
    undo,redo,separator,link,unlink,cleanup”,
    theme_advanced_buttons2 : “formatselect,styleselect,spellchecker,separator,fullscreen”,
    theme_advanced_buttons3 : “”,
    content_css : “style.css”,
    setup : function (ed) {
    ed.onKeyDown.add(
    function (ed, evt) {
    document.form1.deslen.value = tinyMCE.activeEditor.getContent().replace(/]+>/g, ”).length;
    }
    );
    }
    });

    Thanks in advance

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>