今回のテーマ
さてさて。だいぶdojoにも慣れてきましたし、ちょっとしたアプリを作ってみましょうか。 hello, world だけじゃつまんないですもんね。
手頃ないいネタないかなー、って面白そうなAPIありましたよ。
みんな大好きgithub、のAPIですね。マークダウンで書いたテキストを渡すと、それをHTMLに変換したものを返してくれます。便利便利♪これを使って、簡易マークダウンエディタ作りましょう。手順はこんな感じ。
- 画面にはテキストエリアがあって
- そこにmarkdownで入力したテキストをajaxってサーバにpost
- レスポンスのHTMLを描画
dojoで部品を探す
上記手順で、ajaxでサーバとやり取りする部分は前々回あたりでやりましたね。となると、今回やるべきは
- テキストを(markdownで)入力するところ
- サーバ通信するきっかけ
- テキストを(HTMLで)出力するところ
UI案
案1:入力するところと、出力するところを横に並べて、間のボタンクリックのタイミングでサーバ通信する、とか?
案2:入力するところタブと、出力するところタブを作って、タブ切り替えのタイミングでサーバ通信する、とか?
イメージ図。どちらでもできそうですね。でもせっかくdojo使うので面白いやつでいきましょう。
InlineEditBox
dijitの部品であるInlineEditBoxは、その名の通りインラインのeditboxです。…つ、つまり一見普通のHTML要素をクリックするとその部分がテキストエディタになって、編集することができます。編集後はもともと普通のHTML要素がアップデートされます。
言葉で説明するより、testを見ると一目瞭然ですね。
これって、先ほど述べた今回欲しいUIの3つの条件にばっちり満たしますよね。
こいつは使えそうってのは分かったけど、具体的にどう書けば良いのか?最近のバージョンに対応した素敵な解説本でも出ていれば、それを読みたいところですがそうもいかないので、公式のドキュメントに頼ります。まあdojoに限らないですけど
この2つ(とソース)があればなんとかなるもんです。dojoはこの2つとも充実してます。今回もそれをもとに、プロパティはこんな感じで設定しますよ。
- 表示はHTMLで行いたいので、renderAsHtmlをtrueに。
- 登録するボタンを表示したいので、autoSaveをfalseに。
- 登録するボタンのラベル表示が「保存」だとなんなんで、buttonSaveを "preview"に。
- 登録するボタンを押した時にxhr通信をしたいので、onChangeにその旨を記述。
コードで書くとこんな感じになります。
mdEditor = new InlineEditBox({ editor: Textarea, renderAsHtml: true, buttonSave: "preview", buttonCancel: "cancel", autoSave: false, onClick: function(){ // クリックされたときには、markdown形式の方のテキストをセット this.set("value", inputString); }, onChange: function(){ var mdEditorVal = this.get("value"); if (string.trim(mdEditorVal) != string.trim(previewString)){ // ajaxするところ request.post( "./md", { data:{ text: mdEditorVal } }).then( function(text){ // うまく結果を受け取ったらHTMLになったテキストをセット inputString = mdEditorVal; previewString = text; mdEditor.set("value", text); }, function(error){ console.log("An error occurred: " + error); } ); } } }, "markdown_editor"); // ターゲットdomのid
サーバー側を駆け足で
サーバー側はメインとなるmarkdownエンジンは前述のとおりgithubなんで、特になんもないです。ただ、JSONPのAPIがないんで、プロキシってあげます。個人的に今年はpython勉強年なんで、pythonのbottle.pyを使ってみました。
@post('/md') def md(): requestedParam = request.POST params = dict(text=requestedParam.text, mode="gfm") res = urlopen('https://api.github.com/markdown', json.dumps(params)) return res.read()
簡単便利♪
こんな感じになりました
初期表示
クリックすると…
マークダウンで書いてプレビューを押すと…
HTMLになりました!
全体をgithubにおいておきます。
https://github.com/haseg/dojo-md-editor