RailsでTinyMCEを使う
自分で作っているアプリケーションにリッチテキストなエディタを使いたいと思い、TinyMCEを使うことにした。
通常使う分にはTinyMCEをインクルードして初期化するだけでよいみたいだけど、Ajaxで動的にフォームをロードしているような状況だと、いろいろ問題が出て苦労した。
以下、今回対処した手順をメモ。
フォーム生成時にtinyMCE初期化を行う
通常は、HTMLのロード時にTinyMCEが対象のtextareaを見つけてリッチテキスト化するけど、動的にロードする場合は自分で初期化してやらなければいけない。
以下の記述はlink_to_remoteタグでフォームをロードするという前提。
設定のポイント:
- synchronousにする (synchronousにしないと、次項afterオプションのJavaScript実行時に、tinyMCEが対象のtextareaを見つけられない)
- afterオプションで以下のJavaScriptを実行
tinyMCE.idCounter=0; // "this.getDoc() has no properties"というエラーがやたらと出る対策のため → *1 tinyMCE.execCommand("mceAddControl",true,"targetid"); // targetidはリッチテキスト化するtextareaのid
-
- *1 - エラーの内容と対処はこちらのリンクに示してある 参照
入力したリッチテキストの更新
リッチテキストの実体は、対象のtextareaを隠し、その直下(nextSibling)に挿入されているみたい。
従って、フォームをsubmitする前にエディタに入力されたテキストを本来のtextareaに戻してやらなければならないが、動的ロードした場合だとどうもうまく動かないので、自分で移送してやることにする。
設定のポイント:
- form_remote_tag の beforeオプションに以下のJavaScriptを実行するように設定
copyMCE2TextArea("targetid"); // targetidは対象フォームのID
- copyMCE2TextAreaは以下のようなスクリプト
function copyMce2TextArea(id) { var form = $(id); var areas = form.getElementsByTagName('textarea'); for (var i = 0; i < areas.length; i++) { var area = areas[i]; var frame = area.nextSibling.getElementsByTagName('iframe')[0]; area.value = frame.contentDocument.body.innerHTML; } }
-
- リッチテキストはiframeで挿入されるようだ。数が多くなるとなんか重そう。
- iframeのコンテンツはcontentDocumentプロパティで取得できる。