Movable Type のリッチエディタ(TinyMCE)に文字数カウント機能を追加します。
本文フィールドで文字カウント - MTQ | Movable Type ユーザーコミュニティ という質問を見つけましたので、Movable Type の本文欄で使われているリッチエディタ(TinyMCE)に文字数カウント機能を追加してみます。
下記のコードで文字数を表示するためのコードを追加します。
jQuery(function($){
var l = $('#editor-input-content').val().replace(/<.*?>|\n/g, '').length;
var statusHTML = '<span>文字数 : <span id="current-length">' + l + '</span> / </span>';
$('#field-convert_breaks').prepend(statusHTML);
});
リッチテキストで入力された実際のテキストは $('#editor-input-content')
に入っていますので(リッチテキスト保存後)、この値を取得して現在の文字数を表示します。
次に、TinyMEC を拡張して、onKeyUp
イベントで文字数を取得して、追加した HTML に文字数を入れていきます。
var config = MT.Editor.TinyMCE.config;
config.setup = function(ed) {
ed.onKeyUp.add(function(ed, e) {
document.getElementById('current-length').innerHTML = ed.getBody().textContent.length;
});
};
上記の ed.onKeyUp.add
でキーが押されて上がったタイミングで文字数を取得して表示しています。
onKeyUp
の他にも onKeyDown
と onKeyPress
もありますが、 onKeyPress
は日本語入力時やエンターで確定したときには呼ばれないようです。
このコード全体を、管理画面の js_include
変数に追加します。
<mt:setvarblock name="js_include" append="1">
<script>
jQuery(function($){
var l = $('#editor-input-content').val().replace(/<.*?>|\n/g, '').length;
var statusHTML = '<span>文字数 : <span id="current-length">' + l + '</span> / </span>';
$('#field-convert_breaks').prepend(statusHTML);
});
var config = MT.Editor.TinyMCE.config;
config.setup = function(ed) {
ed.onKeyUp.add(function(ed, e) {
document.getElementById('current-length').innerHTML = ed.getBody().textContent.length;
});
};
</script>
</mt:setvarblock>
これを管理画面に反映させるには、alt-tmpl を使う方法と MTAppjQuery を使う方法(オススメ)があります。
alt-tmpl を使う場合は、mt/tmpl/cms/edit_entry.tmpl の中の、
<mt:include name="include/header.tmpl" id="header_include">
の手前に上記のコードを挿入します。
MTAppjQuery があれば、下記のように全体を mt:If
で囲って記事編集画面にだけ適用するようにして、反映させたいウェブサイト/ブログの MTAppjQuery プラグイン設定の「変数 js_include に追加(の直前)」欄に入力すればOKです。
<mt:If name="mtappVars" key="screen_id" eq="edit-entry">
<mt:setvarblock name="js_include" append="1">
<script>
jQuery(function($){
var l = $('#editor-input-content').val().replace(/<.*?>|\n/g, '').length;
var statusHTML = '<span>文字数 : <span id="current-length">' + l + '</span> / </span>';
$('#field-convert_breaks').prepend(statusHTML);
});
var config = MT.Editor.TinyMCE.config;
config.setup = function(ed) {
ed.onKeyUp.add(function(ed, e) {
document.getElementById('current-length').innerHTML = ed.getBody().textContent.length;
});
};
</script>
</mt:setvarblock>
</mt:If>
下記のようなご指摘をいただきました。
ひとつ問題がありそうです。複数のリッチテキストフィールドがMTAppApplyTinyMCEなどで複数適応している場合、入力時に他のリッチテキストフィールドと文字数が干渉してしまうようです。
今回の方法では、 MT.Editor.TinyMCE.config
に設定しているので、複数のフィールドでリッチエディタを適用している場合はご指摘のように文字数が干渉してしまいます。「複数のフィールドで」と言いましたが、そもそもデフォルトでは本文欄と続き欄の2箇所で使用しているので干渉してしまいますね。
ちなみに、「MTAppApplyTinyMCE」というのは、概要欄やテキスト(複数行)のカスタムフィールドを簡単にリッチテキストエディタに変更することができる MTAppjQuery プラグインのメソッドです。
そこで、onKeyUp
イベントの中で、下記のように適用されているフィールドによって処理を分岐することができます。
ed.onKeyUp.add(function(ed, e) {
if (ed.id === "editor-input-content") {
document.getElementById('current-length').innerHTML = ed.getBody().textContent.length;
}
});
このように ed.id
でエディタが適用されているフィールドの ID を取得することができます。本文欄であれば editor-input-content
で、続き欄であれば editor-input-extended
となります。
これを利用して、文字数を表示する要素をフィールドごとに用意しておけば良いでしょう(ここではその方法は割愛します)。
以上です。