Twitter Bootstrap のモーダルを使ってみた (ソースコード解説)

[Milkodeの0.9.3と0.9.4](http://d.hatena.ne.jp/tuto0621/20121116/1353030180)でTwitter Bootstrap のモーダルを使ってみたので、実際に使ったコードを示しながら使い方をまとめてみました。

![modail00](http://cdn-ak.f.st-hatena.com/images/fotolife/t/tuto0621/20121006/20121006153340_original.jpg)

## モーダルって何？
[モーダルダイアログとは【IT用語辞典】](http://e-words.jp/w/E383A2E383BCE38380E383ABE38380E382A4E382A2E383ADE382B0.html)

JavaScriptの`alert`等でも実現出来ますがデザインを変更することが出来ません。Bootstrapのモーダルを使えばHTMLを使って実現することが可能です。

## どこで使われているの？
![modal01](http://cdn-ak.f.st-hatena.com/images/fotolife/t/tuto0621/20121117/20121117012552_original.jpg?1353083245)

「パッケージを更新」を押した時のウィンドウに使っています。

## ソースコード解説
ソースコードと照らし合わせながら読むと分かりやすいです。

[milkode-0.9.4 - Kodeworld](http://kodeworld.ongaeshi.me/home/milkode-0.9.4?query=&shead=package)

## /milkode-0.9.4/lib/milkode/cdweb/views/layout.haml:7
```layout.haml
    %link(rel="stylesheet" href="/css/bootstrap.min.css"  type="text/css" media="all")
```

- Hamlで書いてます
- Bootstrap関連のcss, js を読み込んでいます。8行目、23行目も同様です。

[実際のソースコードへ](http://kodeworld.ongaeshi.me/home/milkode-0.9.4/lib/milkode/cdweb/views/layout.haml?query=bootstrap&shead=package#n7)

## /milkode-0.9.4/lib/milkode/cdweb/app.rb:191
```app.rb
    <div id="updateModal" class="modal hide fade">
      <div class="modal-header">
        <a href="#" class="close" data-dismiss="modal">&times;</a>
        <h3>パッケージを更新</h3>
      </div>
      <div class="modal-body">
        <h4>#{modal_body}</h4>
      </div>
      <div class="modal-footer">
        <a href="#" id="updateCancel" class="btn" data-dismiss="modal">Cancel</a>
        <a href="#" id="updateOk" class="btn btn-primary" data-loading-text="Updating..." milkode-package-name="#{package_name}"">OK</a>
      </div>
    </div>
```

- モーダルウィンドを作成します。hideクラスを指定すると最初は消えてくれます。

[実際のソースコードへ](http://kodeworld.ongaeshi.me/home/milkode-0.9.4/lib/milkode/cdweb/app.rb?shead=package#n191)

## /milkode-0.9.4/lib/milkode/cdweb/app.rb:188
```app.rb
    #{headicon('view-refresh-4.png')} <a href="#updateModal" class="headmenu" data-toggle="modal">パッケージを更新</a>
```

- モーダルウィンドウへのリンクです。クリックするとモーダルが出現します。

[実際のソースコードへ](http://kodeworld.ongaeshi.me/home/milkode-0.9.4/lib/milkode/cdweb/app.rb?shead=package#n188)

## /milkode-0.9.4/lib/milkode/cdweb/public/js/milkode.js:88
```milkode.js
  $("#updateOk").click(function (e) {
    update_package($("#updateOk").attr("milkode-package-name"));
    return false;
  });
```

- ここからJavaScript(とjQuery)です。
- OKボタンを押した時の処理です。 update_package関数を読んでいます。
- キャンセルボタンを押した時や画面外をクリックした時の挙動はデフォルトで提供されています。

[実際のソースコードへ](http://kodeworld.ongaeshi.me/home/milkode-0.9.4/lib/milkode/cdweb/public/js/milkode.js?shead=package#n88)

## /milkode-0.9.4/lib/milkode/cdweb/public/js/milkode.js:105
```milkode.js
function update_package(package_name)
{
  // click button
  $("#updateModal .modal-body").html("<h4>更新中... <img src='/images/waiting.gif'/></h4>");
  $("#updateCancel").addClass("hide");
  $("#updateOk").button('loading').off('click');

  // update end
  $.post(
    '/command',
    {
      kind: 'update',
      name: package_name
    },
    function (data) {
      $("#updateModal .modal-body").html("<h4>実行結果</h4>" + "<p>" + data + "</p>");
      $("#updateOk").button('reset').attr("data-dismiss", "modal").text("Close").on('click', function () { location.reload(); });
    }
  );
}
```

- update_package() 関数本体です。
- モーダルの表示を'更新中・・'書き換えます
- post '/command' をアプリ本体に送り、結果が返ってきたら書き換えます。

[実際のソースコードへ](http://kodeworld.ongaeshi.me/home/milkode-0.9.4/lib/milkode/cdweb/public/js/milkode.js?shead=package#n105)

## まとめ
紹介した全てのソースコードです、Milkodeのダイレクトパス指定を使ってコードの流れを表現しています。

[全てのソースコードをまとめて読む](http://kodeworld.ongaeshi.me/home/milkode-0.9.4?query=%2Fmilkode-0.9.4%2Flib%2Fmilkode%2Fcdweb%2Fviews%2Flayout.haml%3A7+%2Fmilkode-0.9.4%2Flib%2Fmilkode%2Fcdweb%2Fapp.rb%3A191+%2Fmilkode-0.9.4%2Flib%2Fmilkode%2Fcdweb%2Fapp.rb%3A188+%2Fmilkode-0.9.4%2Flib%2Fmilkode%2Fcdweb%2Fpublic%2Fjs%2Fmilkode.js%3A88+%2Fmilkode-0.9.4%2Flib%2Fmilkode%2Fcdweb%2Fpublic%2Fjs%2Fmilkode.js%3A105&shead=package=package)


ソースコード検索エンジンと連携しながら生きたコードを解説する、という試みを試してみたのですがいかがだったでしょうか？感想等ありましたら教えてもらえると次回への励みになります。