Question

I am using CKEditor for my wysiwyg editor and I need to monitor and limit the character count as they are typing I have a jquery script that works fine for a normal TextArea

<script type ="text/javascript" language="javascript">
    function limitChars(textid, limit, infodiv) {
        var text = $('.' + textid).val();
        var textlength = text.length;
        if (textlength > limit) {
            $('#' + infodiv).html('You cannot write more then ' + limit + ' characters!');
            $('#' + textid).val(text.substr(0, limit));
            return false;
        }
        else {
            $('#' + infodiv).html('You have ' + (limit - textlength) + ' characters left.');
            return true;
        }
    }

    $(function() {

        $('.comment-1').keyup(function() {
            limitChars('comment-1', 1000, 'charlimitinfo-1');
        })
    });

</script>

However this doesn't seem to work for when the textArea is replaced with the CKEditor any ideas?

Was it helpful?

Solution

If you can get the contents of the CKEditor as some other posts describe I have an idea about how to get the count of the characters entered. Once you have the contents, say

<b><span class="redText">H</span>ello <span>World!</span></b>

you can set that to the innerHTML of a hidden div, and then get the count of characters in the innerText of that div.

var elem = document.getElementById('hiddenTestDiv');
elem.innerHTML = '<b><span class="redText">H</span>ello <span>World!</span></b>';
var innerText = elem.innerText;  // equals 'Hello World!'
var contentLength = elem.innerText.length; // equals 12

I'd say it's not a perfect solution (for example just <hr> in your content will return 0 for length of innerText), but it may be close enough to work for you. It's kind of a strange situation counting the length of content of html, as Pekka said things like the length of a <hr> tag are open to interpretation.

OTHER TIPS

You can't grab the content of ckeditor so easily, for example with jquery and $("iframe").contents()... cause the ckeditor is not ready when your code fires. So you need to bind some functions on events when the instance of the editor is ready. After that, strip out the tags, trim the whitespaces from the beginning and the end and the counting can begin :)

    <input type="text" name="count" id="count" />
    <textarea id="ck"></textarea>
    <script type="text/javascript">
    $(document).ready(function()
    {
        var editor = CKEDITOR.replace('ck');
        editor.on("instanceReady", function(){
            this.document.on("keyup", ck_jq);
            this.document.on("paste", ck_jq);
        });

    });

    function ck_jq()
    {
        var len = CKEDITOR.instances['ck'].getData().replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, '').replace(/^\s+|\s+$/g, '');
        $("#count").val(len.length);
    }

    </script>

HTH :)

The textarea is only a fallback element, and not updated live with the entered content. You would have to grab the contents of your CKEditor instance. This is definitely possible.

Check out the approaches in this question. that access CKEditor's contents on every content change.

I see a bigger problem for you, though. How many characters does this code have?:

<b><span class="redText">H</span>ello <span>World!</span></b>

(the answer - I think - is twelve)

or this:

<b>  <p style="font-size: 30px; font-weight: bold"></p>  </b>

(the answer - I think - is two spaces)

or this:

<hr>

(the answer - I think - is one, but that's down to interpretation really)

these are all conceivable strings that occur while writing and deleting text in CKEditor.

Assuming you want to count all characters without HTML tags, ignoring additional elements like images or horizontal lines, there is a strip_tags() function for JavaScript that you can use to strip down the data.

The CKEditor actually renders as an Iframe, You can get the contents from the Iframe (http://simple.procoding.net/2008/03/21/how-to-access-iframe-in-jquery/), although it isn't going to be easy. I would second @Pekka's concern about HTML and how you are going to determine character count.

//You can get real content of CKedit by using document.getBody().getText() as below: //
//Sample:

//join_content is Id of ckeditor
//Editor Html: {$oneJoinInfo['description']} {form::editor('join_content', 'full','','','',1)}

var join_contentVal = CKEDITOR.instances.join_content.document.getBody().getText();      
  if(strlen(join_contentVal) > 1000){                              
   return false;           
 }   



function save()
    {
    var caseText = CKEDITOR.instances.caseText.getData();  
    var caseforlen = CKEDITOR.instances.caseText.document.getBody().getText();
    if (strlen(caseforlen) > 4000) {
        alert("maxnum is 2000");
        return;
    }

}


function strlen(str) { 
    var regExp = new RegExp(" ","g");
    str = str.replace(regExp , ""); 
    str = str.replace(/\r\n/g,"");
    var realLength = 0, len = str.length, charCode = -1; 
    for (var i = 0; i < len; i++) { 
        charCode = str.charCodeAt(i); 
        if (charCode >= 0 && charCode <= 128) realLength += 1; 
        else realLength += 2; 
    } 
    return realLength; 
};  
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);
               }
}

CKEDITOR.replace('local',{
                MaxLength: 255
});
CKEDITOR.instances.local.on('key', checkLength);
CKEDITOR.instances.local.on('paste', checkLength);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top