CKEditor Maximum Length

Recently I needed to implement an HTML editor in an old ASP.NET 1.1 application. This application is a sort of generic survey application that has been abused a long time ago to not be so generic anymore, and this is put mildly. Our client was instructed by someone else that text entered into a description field needed to conform to web standards and we should use one of two free HTML editors. Another requirement was that the text could contain a maximum of 350 characters.

We had the choice of TinyMCE or CKEditor. Without much investigation we’ve gone with CKEditor, because it seemed the least focused on PHP in their examples, but to be honest we’ve spent no more than 5 minutes on the site and it shouldn’t really depend on the server side language we use, but the choice was made! As a side note, I did not know that WordPress uses TinyMCE.

It was very easy to install the editor and get it running. With a simple bit of javascript I was able to change a normal HTML textarea into an editor with the options I wanted.

CKEDITOR.replace('TEXTAREA_ID',
{
	toolbar: [['CharCount'],
		['Cut','Copy','Paste','PasteText'],
		['SelectAll'],
		['Bold', 'Italic', '-', 'NumberedList', 'BulletedList'],
		['SpecialChar']]
});

So far so good. But the most difficult and annoying part was yet to come. CKEditor (and I believe TinyMCE as well) does not have a built in mechanism to restrict the number of characters entered. So we had to add something ourselves. There are some posts and sites that have options for this and I used one of them and modified it to my liking. The original discussion can be found here.

Once you have something like that in place you need to make up your mind about what to count. Do you need to count the visible text or do you count all the HTML formatting too? We have chosen – together with our client – to count the text you see and used a big line of replace code from the above link.

Something we added was this functionality to work with pasted text as well and we removed a visible counter. Last but not least we changed the code to be a bit more generic by using the event arguments of the events to get to the editor and use the configuration for some settings tied to the editor you are working with. This way the function works for any CKEditor on the page as long as you set some things when replacing your textarea.

I am still not 100% happy with the result as pasting a bit of text that will go over the maximum amount of characters will just get undone. Also sometimes it seems a bit buggy with pasting or typing fast, but in normal operation it functions quite well. Following is the new initialization of the editor.

CKEDITOR.replace('TEXTAREA_ID',
{
	toolbar: [['CharCount'],
		['Cut','Copy','Paste','PasteText'],
		['SelectAll'],
		['Bold', 'Italic', '-', 'NumberedList', 'BulletedList'],
		['SpecialChar']],
	MaxLength: 350
});
CKEDITOR.instances.TEXTAREA_ID.on('key', checkLength);
CKEDITOR.instances.TEXTAREA_ID.on('paste', checkLength);

Here are the functions we added to the HTML head section of our page.

function getCurrentCount(editor)
{
	var currentLength = editor.getData()
		.replace(/<[^>]*>/g, '')
		.replace(/\s+/g, ' ')
		.replace(/&\w+;/g ,'X')
		.replace(/^\s*/g, '')
		.replace(/\s*$/g, '')
		.length;
 
	return currentLength;
}
 
function checkLength(evt)
{
	var stopHandler = false;
	var currentLength = getCurrentCount(evt.editor);
	var maximumLength = 350;
 
	if(evt.editor.config.MaxLength)
	{
		maximumLength = evt.editor.config.MaxLength;
	}
 
	if(!evt.editor.config.LockedInitialized)
	{
		evt.editor.config.LockedInitialized = 1;
		evt.editor.config.Locked = 0;
	}
 
	if(evt.data)
	{
		if(evt.data.html)
		{
			currentLength += evt.data.html.length;
		}
		else if(evt.data.text)
		{
			currentLength += evt.data.text.length;
		}
	}
 
	if(!stopHandler && currentLength >= maximumLength)
	{
		if ( !evt.editor.config.Locked )
		{
			// Record the last legal content.
			evt.editor.fire( 'saveSnapshot' );
			evt.editor.config.Locked = 1;
			// Cancel the keystroke.
			evt.cancel();
		}
		else
			// Check after this key has effected.
			setTimeout( function()
			{
				// Rollback the illegal one.
				if( getCurrentCount(evt.editor) > maximumLength )
					evt.editor.execCommand( 'undo' );
				else
					evt.editor.config.Locked = 0;
			}, 0);
	}
}

I have to apologise for the formatting. I have not figured out how to get better looking code snippets in WordPress yet. Please give me some tips if you know how to properly handle those.

Edit 2010-06-16: With some extra effort I formatted the code blocks better. It still isn’t how it should be, because real code blocks get formatted pretty strange and ugly with my current theme, but it looks ok and readable now.

Edit 2010-06-17: I installed a new plugin called WP-Syntax that uses GeSHi for syntax highlighting in code blocks. Together with my current theme it looks nice after some tweaking of the plugin stylesheet, but they don’t work well together when I use line numbers, so you won’t find those.

Edit 2010-07-19: I ended up removing all this custom work a few weeks ago, because in the end it just didn’t feel right and was kind of buggy. The client didn’t like it and the initial specification was that we just checked the length after saving, which is the default way for other fields in this application and is not very bad due to how it works overall. (It still saves, it just shows some kind of ‘incomplete’ message)

Leave a comment ?

27 Comments.

  1. Diego Garcia

    Is the best post that i found to get this validation, thanks a lot

  2. Your script has html encoded some of the ampersands, greater thans, etc.

  3. @Jon: You are right. I updated the code and think it’s ok now. Thanks.

  4. Thanks Man! It was extremely helpful to me.

  5. This is brilliant. Do you know how to add a counter so the user can see how close they are getting to the limit?

  6. @Mike: Don’t know exactly anymore how stuff like that should be done and I haven’t even got this in place anymore. But there is a way to add your own toolbar buttons/widgets (see the CharCount in my example) and you could use that toolbar item to display the result of the getCurrentCount javascript method.

  7. Thanks Rodi. You’re completely right, it was really easy (you’d already done all the work in your code). There aren’t many solutions to this out there – yours is the best among them!

  8. Can you please provide full working example. i am not able get it working

  9. @sibu: i think this is enough. And besides I don’t really like the solution myself, because it’s alittle buggy like this. I don’t use this myself anymore.

  10. Hi :razz: could you plz tell me how can I add a character counter with ckeditor ?

  11. @Solutionfinder: Don’t exactly know how to add a new toolbarbutton on ckeditor, but look that one up. Then just use the javascript functions in this post to count the characters and let the button show it.

    But as I said earlier, this solution was a bit buggy for me and I don’t (and probably won’t) even use it anymore.

    There is a reason the authors of ckeditor (and other editors) didn’t include this functionality. :)

  12. Hello, I’m using your script, and it is very good!
    I’m making a counter for the user see, but I’m having a problem with the currentLength, it’s getting the text length before inserting a letter (so one letter is late), I wanted it to get the text after I press a letter, I was trying to add the event “keydown”…
    CKEDITOR.instances.TEXTAREA_ID.on(‘keydown’, checkLength);

    …but it doesn’t work, do you have a list of events that could work with it? or a solution for my problem?

    Thanks :smile:

  13. @Gabriel: Good you like it and are using it. You could try using the keyup event in stead. If that still doesn’t work, you might workaround with a dirty solution by adding 1 (one) to the length you have (checkLength + 1)

  14. Hi, I really liked your plugin, however I got some problems in CKEditor and I would ask your help. I need to block some special characters like: ☺ ☻ ♥ ♦ ♣ ♠ ○ ◘ § ♪
    Would you know a plugin or a feature that could blocks those characters?

    grateful

  15. @hideki: in the event (checkLength in my example) you could check if the character entered is one of those and if it is, use evt.cancel just like I already do when the length is too high…

  16. It is really really helped me a lot..

    Thank you so much. :smile:

  17. Seems to work well, Thanks!
    Since I’m not a Js Expert as I work most with PHP, I didn’t know how to make the counter visible :???:

  18. @JACK: You could add a new toolbar “button” that shows the current count (I haven’t done anything with CKEditor in a long time, so I’m not sure how exactly) or you could have a seperate textbox near the text editor and update that one with the current count. The latter should not be that difficult. Just update the new textbox (or div / span, whatever you want) with “currentLength” right after you calculated it. (just before the last big if-block)

  19. what can i do if i have textarea id dynamic

  20. @Paul: You need to get the dynamic id inside your script too. I don’t know what kind of dynamic you mean, but if it’s like a server-side script that determines the id, you should dynamically insert the initialization script into the page together with this dynamic id.
    I might not understand exactly, but if you can have a dynamic id in one place (the text area element/control), it should be possible to have the same dynamic id somewhere else on the same page (in the initialization javascript).

  21. How would I go about adding a visible character counter?

  22. @Crais: See my reply @JACK. I haven’t done anything with CKEditor in a long time, so I’m not sure about the details, but you can add a toolbar button and then update it (or the div inside or something) with the current length when it gets updated.

  23. In this example i restrict max character’s length 10 and i copy some string of 12 character it will accept that string

  24. @jhon: Like I said earlier, I did not end up using this, because I found it too buggy; I haven’tl ooked into ckeditor and this solution in quite some time, so I cannot comment on any improvements in ckeditor or better solutions to this problem, unfortunately. I hope you can find a solutions that suits you.
    I do think the solution in my post is workable, but you still need to check the length after posting and then decide what to do if it does not fit. You could just cut off the characters at the end or notify the user that the string is too long after all.
    But I think using an editor like ckeditor is for long texts, without any maximum if at all possible. Using it for only 10 characters really defeats its purpose. What kind of formatting do you want in a 10 character string? (I can imaginge the 10 characters was for testing only; if that’s the case, ignore this last comment)

  25. I need to limit the word count in ckeditor plugin.Please help

  26. @diana: It’s been too long ago to give real solid advice, but you should modify the code that counts every character to just count when it registers a space or point an such. Then tweak some to get it right. Hope you can get it to work to your liking.

Leave a Comment


NOTE - You can 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>