TinyMCE, show character count instead of word count
Asked Answered
C

6

20

The title says it all. How do I get TinyMCE to show character count instead of word count?

enter image description here

Cenobite answered 27/12, 2015 at 15:39 Comment(0)
B
11

Write your own plugin.

The following solution is based on this article. The charactercount plugin counts the actual characters that the user sees, all HTML and hidden characters are ignored. The number is updated on every "key up" event.

Character Count Plugin:

tinymce.PluginManager.add('charactercount', function (editor) {
  var self = this;

  function update() {
    editor.theme.panel.find('#charactercount').text(['Characters: {0}', self.getCount()]);
  }

  editor.on('init', function () {
    var statusbar = editor.theme.panel && editor.theme.panel.find('#statusbar')[0];

    if (statusbar) {
      window.setTimeout(function () {
        statusbar.insert({
          type: 'label',
          name: 'charactercount',
          text: ['Characters: {0}', self.getCount()],
          classes: 'charactercount',
          disabled: editor.settings.readonly
        }, 0);

        editor.on('setcontent beforeaddundo', update);

        editor.on('keyup', function (e) {
            update();
        });
      }, 0);
    }
  });

  self.getCount = function () {
    var tx = editor.getContent({ format: 'raw' });
    var decoded = decodeHtml(tx);
    // here we strip all HTML tags
    var decodedStripped = decoded.replace(/(<([^>]+)>)/ig, "").trim();
    var tc = decodedStripped.length;
    return tc;
  };

  function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
  }
});

CSS Tweaks:

/* Optional: Adjust the positioning of the character count text. */
label.mce-charactercount {
  margin: 2px 0 2px 2px;
  padding: 8px;
}

/* Optional: Remove the html path code from the status bar. */
.mce-path {
  display: none !important;
}

TinyMCE Initialization (using jQuery)

$('textarea.tinymce').tinymce({
  plugins: "charactercount",
  statusbar: true,
  init_instance_callback: function (editor) {
    $('.mce-tinymce').show('fast');
    $(editor.getContainer()).find(".mce-path").css("display", "none");
  }
  // ...
});

ps. Use JS minifier.

Bally answered 4/1, 2016 at 9:19 Comment(2)
I tried using this sample. When I walked thru the code, the statusbar variable returned 'undefined' upon getting to the 'if (statusbar) {" line, so naturally that "if" block does not execute. When I tried expanding editor.theme, I could not find a panel object. I am using tinymce ver 5.0.14 because our security people say this is the correct version I need to be using. What could be wrong?Armorial
@Armorial please ask a new question. And Stack Overflow users will help you. I advise preparing JSFiddle (example), that clearly demonstrates how to reproduce your problem, and inserting a link to the JSFiddle in your question.Bally
C
22

wordcount plugin now can count and show characters:

Clicking Word Count in the status bar switches between counting words and characters.

By default mode is "words", but it's pretty easy emulate click in status bar to switch it.

Alter your editor config following way:

tinymce.init({
   plugins: "wordcount",

   // ... 

   init_instance_callback: function (editor) {
      $(editor.getContainer()).find('button.tox-statusbar__wordcount').click();  // if you use jQuery
   }
});

That's all. You have character count now.

Coen answered 25/7, 2019 at 10:43 Comment(3)
It's a terrible hack, but it works. IMHO this should be an option in the plugin itself. I can't imagine why anyone would want to count words by default anyhow.Pinson
It works, i didnt find better solution for v5, @naXa solutions dont workLineberry
Yeah.. But it works! And copy/paste done. I needed the character count because we take the body and send it out via SMS sometimes, so it's useful to know the # characters used.Hallee
B
11

Write your own plugin.

The following solution is based on this article. The charactercount plugin counts the actual characters that the user sees, all HTML and hidden characters are ignored. The number is updated on every "key up" event.

Character Count Plugin:

tinymce.PluginManager.add('charactercount', function (editor) {
  var self = this;

  function update() {
    editor.theme.panel.find('#charactercount').text(['Characters: {0}', self.getCount()]);
  }

  editor.on('init', function () {
    var statusbar = editor.theme.panel && editor.theme.panel.find('#statusbar')[0];

    if (statusbar) {
      window.setTimeout(function () {
        statusbar.insert({
          type: 'label',
          name: 'charactercount',
          text: ['Characters: {0}', self.getCount()],
          classes: 'charactercount',
          disabled: editor.settings.readonly
        }, 0);

        editor.on('setcontent beforeaddundo', update);

        editor.on('keyup', function (e) {
            update();
        });
      }, 0);
    }
  });

  self.getCount = function () {
    var tx = editor.getContent({ format: 'raw' });
    var decoded = decodeHtml(tx);
    // here we strip all HTML tags
    var decodedStripped = decoded.replace(/(<([^>]+)>)/ig, "").trim();
    var tc = decodedStripped.length;
    return tc;
  };

  function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
  }
});

CSS Tweaks:

/* Optional: Adjust the positioning of the character count text. */
label.mce-charactercount {
  margin: 2px 0 2px 2px;
  padding: 8px;
}

/* Optional: Remove the html path code from the status bar. */
.mce-path {
  display: none !important;
}

TinyMCE Initialization (using jQuery)

$('textarea.tinymce').tinymce({
  plugins: "charactercount",
  statusbar: true,
  init_instance_callback: function (editor) {
    $('.mce-tinymce').show('fast');
    $(editor.getContainer()).find(".mce-path").css("display", "none");
  }
  // ...
});

ps. Use JS minifier.

Bally answered 4/1, 2016 at 9:19 Comment(2)
I tried using this sample. When I walked thru the code, the statusbar variable returned 'undefined' upon getting to the 'if (statusbar) {" line, so naturally that "if" block does not execute. When I tried expanding editor.theme, I could not find a panel object. I am using tinymce ver 5.0.14 because our security people say this is the correct version I need to be using. What could be wrong?Armorial
@Armorial please ask a new question. And Stack Overflow users will help you. I advise preparing JSFiddle (example), that clearly demonstrates how to reproduce your problem, and inserting a link to the JSFiddle in your question.Bally
V
8
    init_instance_callback: function (editor) {
editor.on('change', function (e) {
                var length = editor.contentDocument.body.innerText.length;
            });
}

On init add this. length is your character length. Now you need to hide word count and attach a new string with character counter.

Vestibule answered 20/3, 2017 at 10:22 Comment(1)
keyup will be betterDozier
F
4

I was able to set the wordcount plugin to display characters by default by creating a custom version of the silver theme. Looks like in TinyMCE 5.1.6 the way plugins are rendered is set in the theme file. TinyMCE config:

{
    selector: '.tinymce',
    theme: 'silver-custom',
    ...
}

The theme file is a copy of the themes/silver/theme.js and needs to load after TinyMCE.

Changes:

 ...
 function Theme () {
      global$1.add('silver-custom', function (editor) {
 ...

and

...
var renderWordCount = function (editor, providersBackstage) {
    ...
    store: {
        mode: 'memory',
        initialValue: {
        mode: 'characters',
        ...
}
...
Finzer answered 11/2, 2020 at 9:1 Comment(1)
This seems to be the best and easiest way to do this. It also avoids reinventing the wheel.Harlandharle
N
0

I am using this one in production https://gist.github.com/imanilchaudhari/5a121ea6420eb4b8aa7ee70a5f7074e3 since 2017. this plugin is good.

I initially thought charword count comes with the tinymce builtin plugins, but later found that it is a custom one.

It will show number of character in the bottom status bar

enter image description here

Nullipore answered 22/11, 2021 at 12:35 Comment(1)
That script is old and not working with tinymce 5Pickens
S
0

Force one button click in React. The empty dependency array ensures this effect only runs once after the initial render.

useEffect(() => {
    const wordCountButton = document.querySelector('.tox-statusbar__wordcount');

    if(wordCountButton) {
        wordCountButton.click();
    }
}, []);
Suppository answered 18/4 at 17:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.