2018.5.16
最近、Formaでの開発が増えてフルスクラッチとは少し勝手が違い、なかなか思うように動かなくてハマったネタを紹介します。
今回は、Formaアイテムのリッチテキストボックスをアクション設定からではなくスクリプトアイテムから以下の操作を行います。
・・・と、ちょっとマニアックですが、結構面倒だったので紹介しようと思います。
リッチテキストボックスに入力された値(HTML)はFormaアプリテーブルのカラムではバイナリとして登録されています。
無論そのままセレクトしても値はバイナリ(16進数)のままで読めません。
余談ですが、今回の検証で発見したのですがSQLServerでバイナリ型をCASE式を使ってSELECTすると何故か文字化けします。。。
調べても出てこないし、CASE式は使わずに済んだのでひとまず見なかったことにします。
JavaのResultSetを使って取得した場合、バイナリ値は以下、「getBinaryStream」を使用します。
resultSet.getBinaryStream("binary_data");
上記はInputStream型(正確にはデータベースの種類によって異なりますが各JDBCが独自に作成したバイナリを扱うInputStreamクラスを継承したもの?)が返却されます。
どんなデータベースでもInputStream型で帰ってくるはずです。
無論、上記で取ってきてもバイナリのままなので、以下コードを使ってテキストに戻してあげます。
public String convertHTML(InputStream bis) { StringBuilder sb = new StringBuilder(); try { final InputStreamReader isr = new InputStreamReader(bis, Charset.forName("UTF-16BE")); final BufferedReader br = new BufferedReader(isr); try { String line; while ((line = br.readLine()) != null) { sb.append(line); } } finally { IOUtil.closeCloseableQuietly(br); IOUtil.closeCloseableQuietly(isr); } } catch (Exception e) { e.printStackTrace(); } finally { IOUtil.closeCloseableQuietly(bis); } return sb.toString(); }
ここで超重要なのがStreamReaderで文字コード「UTF-16BE」を指定してやることです。
これはハマりました。。。
私が至らなすぎただけかもしれませんが、intra-martはUTF-8を使用していてDBもUTF-8を使うよう設定していたので、見落としていました。
ここにUTF-8を指定すると、それっぽい文字列に復元されますが、使用できるレベルではありません。
これで、リッチテキストに入力した文字列(HTML)が綺麗に復元されます。
この値を使い、今度はFormaアイテムに設定します。
Formaリッチテキストアイテムの識別IDを「el_richtext」とした場合、
window.formaItems.product_80_richtextbox.setItemData.el_richtext({ data: { el_richtext: '<span style="color: #ff00ff; font-size: 24pt;"data-mce-style="color: #ff00ff; font-size: 24pt;"><strong>これはテスト用文書です。</strong></span>' } });
dataオブジェクトの中の「el_richtext」オブジェクトに、バイナリから復元したHTMLを設定してやるとFormaアイテムに表示されます。
今回は以上です。他に設定が厄介そうなアイテムを紹介してゆきます。