• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

How to create a simple real-time word count for editor?

#1
Hi, i'm trying to create a simple word count for the XenForo editor via jquery but i don't know exactly how to access the DOM.

I used this simple javascript code to access a normal input zone:

Code:
function count(){
    var words = $('#title').val().trim().replace(/\s+/gi, ' ').split(' ').length;
    var chars = $('#title').val().length;
    if(chars===0){words=0;}
    $('#titlecounter').html('('+ chars +')');
}

 $('#title').on('keyup propertychange paste', function(){
     count();
    });
But i don't know how to access the Editor content (Redactor). Someone now how to access it via jquery ? maybe @cclaerhout ?
 

Chris D

XenForo developer
Staff member
#3
The editor contents are synced to a hidden textarea, so you should target that and retrieve its value, e.g. the most basic way:

Code:
$('textarea.BbCodeWysiwygEditor').val();
One thing that's worth bearing in mind is the editor contents contain HTML. You will have to factor in how a string such as:

<font color="#ff0000">This is a string</font>

...is counted. You may need some function that strips out all HTML and then counts what is left.
 
#4
The editor contents are synced to a hidden textarea, so you should target that and retrieve its value, e.g. the most basic way:

Code:
$('textarea.BbCodeWysiwygEditor').val();
One thing that's worth bearing in mind is the editor contents contain HTML. You will have to factor in how a string such as:

<font color="#ff0000">This is a string</font>

...is counted. You may need some function that strips out all HTML and then counts what is left.
Nice, this is a good, but i need as you said some kind of "HTML code cleaner".
 

Chris D

XenForo developer
Staff member
#5
Try this... (untested):

Code:
$("<div/>").html($('textarea.BbCodeWysiwygEditor').val()).text()
That creates a div, populates the inner HTML with the HTML from the hidden textarea and then returns the text value of the div (which strips the HTML).
 

cclaerhout

Well-known member
#7
I don't think the textarea is synchronized with the RTE in real time, so the value given by the above code won't be accurate, unless if you want to get this value when the form is sent. Otherwise, you will have to use the Redactor functions to get this value and apply a filter based on what kind of words or characters you want to match for your counter. Don't forget, the JS regex engine doesn't support unicode. To clean the RTE content and implement your counter, you can take a look at the TinyMCE wordcount plugin (LGPL licence). Good luck.
 

cclaerhout

Well-known member
#9
It is, otherwise I wouldn't have suggested its use.
Then "$('textarea.BbCodeWysiwygEditor').val()" should be enough to get the code (creating a wrapper to get its text is redundant here), but not to bind an external function on it. With this way of doing, the syncCode will have to be extended to trigger an event and this will not be clean. The cleanest solution is simply to make a plugin. Redactor has already one but it has been coded with its new api (ref). This means on XenForo it will have to be coded with the editor former API and with the XenForo self API (for the init):
Code:
  $(document).on('EditorInit', function(e, data){
     var editor = data.editor,
       config = data.config;

     RedactorPlugins.myPlugin = {
       init: function()
       {
         this.$editor.on('keyup', $.proxy(function(e)
         {
           var html = this.$editor.html();
           console.log(html);
           //to do
         }, this));   
       }
     };

     if(typeof config.plugins === undefined || !$.isArray(config.plugins)){
       config.plugins = ['myPlugin'];
     }else{
       config.plugins.push('myPlugin');
     }
   });
 

Chris D

XenForo developer
Staff member
#10
Then "$('textarea.BbCodeWysiwygEditor').val()" should be enough to get the code
It is, to get the raw HTML code, yes.

(creating a wrapper to get its text is redundant here)
It isn't redundant because the textarea value contains the HTML contents of the editor, and to accurately count the word/characters, the HTML tags need to be removed. Using the wrapper and text method removes those tags.
 

cclaerhout

Well-known member
#11
Using the wrapper and text method removes those tags.
Oh ok, then use this code, it will be faster:
Code:
$($('textarea.BbCodeWysiwygEditor').val()).text();
The problems of this solution remain the same:
  1. it fails to give a proper way to listen the modifications and bind a function on it
  2. the counter will be inaccurate since, for example, some whitespace will be missing (the one of the paragraphs), that's why all counters plugins using some custom regex.
 
#12
Oh ok, then use this code, it will be faster:
Code:
$($('textarea.BbCodeWysiwygEditor').val()).text();
The problems of this solution remain the same:
  1. it fails to give a proper way to listen the modifications and bind a function on it
  2. the counter will be inaccurate since, for example, some whitespace will be missing (the one of the paragraphs), that's why all counters plugins using some custom regex.
It is, to get the raw HTML code, yes.


It isn't redundant because the textarea value contains the HTML contents of the editor, and to accurately count the word/characters, the HTML tags need to be removed. Using the wrapper and text method removes those tags.
A little problem i found with the code. The event keyup don't fire with $('textarea.BbCodeWysiwygEditor').

How can i make this code fire?
 
#16
The editor contents are synced to a hidden textarea, so you should target that and retrieve its value, e.g. the most basic way:

Code:
$('textarea.BbCodeWysiwygEditor').val();
One thing that's worth bearing in mind is the editor contents contain HTML. You will have to factor in how a string such as:

<font color="#ff0000">This is a string</font>

...is counted. You may need some function that strips out all HTML and then counts what is left.
I know this topic is too old but are there anyway to change the content of the editor by js?