knockout.js クリックしたデータをレイアウトを変えて表示

2012/04/13

ソース

  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4. <meta charset="UTF−8">
  5. <title>knockoutjsちゅーとりある:SPA(webMail)クリックしたデータをレイアウトを変えて表示</title>
  6. <script type="text/javascript" src="jquery−1.5.1.min.js"></script>
  7. <script type="text/javascript" src="knockout−2.1.0beta.js"></script>
  8.  
  9. <style>
  10. body { font−family: Helvetica, Arial }
  11. input:not([type]), input[type=text], input[type=password], select { background−color: #FFFFCC; border: 1px solid gray; padding: 2px; }
  12. body { font−family: Helvetica, Arial}
  13.  
  14. .folders { background−color: #bbb; list−style−type: none; padding: 0; margin: 0; border−radius: 7px; background−image: −webkit−gradient(linear, left top, left bottom, color−stop(0, #d6d6d6), color−stop(0.4, #c0c0c0), color−stop(1,#a4a4a4)); margin: 10px 0 16px 0; font−size: 0px; }
  15. .folders li:hover { background−color: #ddd; }
  16. .folders li:first−child { border−left: none; border−radius: 7px 0 0 7px; }
  17. .folders li { font−size: 16px; font−weight: bold; display: inline−block; padding: 0.5em 1.5em; cursor: pointer; color: #444; text−shadow: #f7f7f7 0 1px 1px; border−left: 1px solid #ddd; border−right: 1px solid #888; }
  18. .folders li { *display: inline !important; } /* IE7 only */
  19. .folders .selected { background−color: #444 !important; color: white; text−shadow:none; border−right−color: #aaa; border−left: none; box−shadow:inset 1px 2px 6px #070707; }
  20.  
  21. .mails { width: 100%; table−layout:fixed; border−spacing: 0; }
  22. .mails thead { background−color: #bbb; font−weight: bold; color: #444; text−shadow: #f7f7f7 0 1px 1px; }
  23. .mails tbody tr:hover { cursor: pointer; background−color: #68c !important; color: White; }
  24. .mails th, .mails td { text−align:left; padding: 0.4em 0.3em; white−space: nowrap; overflow: hidden; text−overflow: ellipsis; }
  25. .mails th { border−left: 1px solid #ddd; border−right: 1px solid #888; padding: 0.4em 0 0.3em 0.7em; }
  26. .mails th:nth−child(1), .mails td:nth−child(1) { width: 20%; }
  27. .mails th:nth−child(2), .mails td:nth−child(2) { width: 15%; }
  28. .mails th:nth−child(3), .mails td:nth−child(3) { width: 45%; }
  29. .mails th:nth−child(4), .mails td:nth−child(4) { width: 15%; }
  30. .mails th:last−child { border−right: none }
  31. .mails tr:nth−child(even) { background−color: #EEE; }
  32.  
  33. .viewMail .mailInfo { background−color: #dae0e8; padding: 1em 1em 0.5em 1.25em; border−radius: 1em; }
  34. .viewMail .mailInfo h1 { margin−top: 0.2em; font−size: 130%; }
  35. .viewMail .mailInfo label { color: #777; font−weight: bold; min−width: 2.75em; text−align:right; display: inline−block; }
  36. .viewMail .message { padding: 0 1.25em; }
  37. </style>
  38.  
  39. <script type="text/javascript">
  40.   $(document).ready(function () {
  41.     function WebmailViewModel() {
  42.       var self = this;
  43.  
  44.       // フォルダのデータ
  45.       self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
  46.  
  47.       // データに対してIDをつけるけど、とりあえず何もなしと思われる。
  48.       self.chosenFolderId = ko.observable();
  49.       self.chosenFolderData = ko.observable();
  50.       self.chosenMailData = ko.observable();
  51.  
  52.       // フォルダ(InoboxやArchiveなど)をクリックしたときの処理
  53.       self.goToFolder = function(folder) {
  54.         // クリックされたデータを取得:folder(InoboxやArchive)
  55.         self.chosenFolderId(folder);
  56.  
  57.         // メール詳細であるchosenMailDataを非表示にする
  58.         self.chosenMailData(null);
  59.  
  60.         // 「/mail?folder=xxx」(GET送信)の結果をself.chosenFolderDataにいれる
  61.         //$.get('/mail', {folder: folder}, self.chosenFolderData);
  62.  
  63.         // フォルダに合わせて読み込むファイルを変更
  64.         var fileName = "./" + folder + ".txt";
  65.         $.getJSON(fileName, {}, self.chosenFolderData);
  66.       };
  67.  
  68.       // 詳細データの取得
  69.       self.goToMail = function(mail) {
  70.         self.chosenFolderId(mail.folder);
  71.  
  72.         // メール一覧であるchosenFolderDataを非表示にする
  73.         self.chosenFolderData(null);
  74.  
  75.         // 「/mail?mailId=xxx」(GET送信)の結果をself.chosenMailDataにいれる
  76.         //$.get("/mail", { mailId: mail.id }, self.chosenMailData);
  77.  
  78.         // フォルダに合わせて読み込むファイルを変更
  79.         var fileName = "./mail/mailId" + mail.id + ".txt";
  80.         $.getJSON(fileName, {}, self.chosenMailData);
  81.       };
  82.  
  83.       // 最初に表示するフォルダ
  84.       self.goToFolder('Inbox');
  85.     }
  86.  
  87.     ko.applyBindings(new WebmailViewModel());
  88.   });
  89. </script>
  90.  
  91. </head>
  92. <body>
  93.  
  94. <!−− フォルダ一覧 Folders −−>
  95. <ul class="folders" data−bind="foreach: folders">
  96. <li data−bind="text: $data, css: { selected: $data == $root.chosenFolderId() }, click: $root.goToFolder"></li>
  97. </ul>
  98.  
  99. <!−− メール一覧 chosenFolderData −−>
  100. <table class="mails" data−bind="with: chosenFolderData">
  101.   <thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
  102.   <tbody data−bind="foreach: mails">
  103.     <tr data−bind="click: $root.goToMail">
  104.       <td data−bind="text: from"></td>
  105.       <td data−bind="text: to"></td>
  106.       <td data−bind="text: subject"></td>
  107.       <td data−bind="text: date"></td>
  108.     </tr>
  109.   </tbody>
  110. </table>
  111.  
  112. <!−− メール詳細 chosenMailData −−>
  113. <div class="viewMail" data−bind="with: chosenMailData">
  114.   <div class="mailInfo">
  115.     <h1 data−bind="text: subject"></h1>
  116.     <p><label>From</label>: <span data−bind="text: from"></span></p>
  117.     <p><label>To</label>: <span data−bind="text: to"></span></p>
  118.     <p><label>Date</label>: <span data−bind="text: date"></span></p>
  119.   </div>
  120.   <p class="message" data−bind="html: messageContent" />
  121. </div>
  122.  
  123. </body>
  124. </html>

めも

詳細データの表示

112~121行目で詳細データを作成。
103行目のtrタグで「click: $root.goToMail」を指定。これで、trタグがクリックしたら69行目のself.goToMailが実行される。
実行されたら112~121行目が表示される。

一覧や詳細データの非表示

「一覧が表示されているときは、詳細データを非表示。詳細データが表示されてるときは一覧を非表示」ってな感じにする。

まず「一覧が表示されているときは、詳細データを非表示」ってのは53行目の「goToFolder」が実行されたとき。58行目の「self.chosenMailData(null);」で非表示。

次に「詳細データが表示されてるときは一覧を非表示」ってのは69行目の「goToMail」が実行されたとき。73行目の「self.chosenFolderData(null);」で非表示。

使うデータ

61・76行目で「/mail」にパラメーターをつけてGET送信。

自身のテストでやるにはこれは少し面倒なので各パラメーターをつけてGET送信した値を1ファイルずつに変更。
各ファイルはテキストファイルなのでJSONとして読む込むために65・80行目で$.getJSONをしている。

chosenFolderDataのJSONサンプル

{"id":"Inbox","mails":[{"id":1,"from":"Abbot \u003coliver@smoke−stage.xyz\u003e","to":"recatnap@example.com","date":"May 25, 2011","subject":"Booking confirmation #389629244","folder":"Inbox"},{"id":2,"from":"Addison Begoat \u003cupton.oprdrusson@pear−income.xyz\u003e","to":"recatnap@example.com","date":"May 7, 2011","subject":"FW: Associate advice","folder":"Inbox"},{"id":3,"from":"Allistair \u003cleroy72@plane−railway.xyz\u003e","to":"recatnap@example.com","date":"May 19, 2011","subject":"RE: Phone call tomorrow 5 o\u0027clock","folder":"Inbox"},{"id":4,"from":"emmanuel26@ghost.xyz","to":"recatnap@example.com","date":"May 22, 2011","subject":"Completing basketball project","folder":"Inbox"},{"id":5,"from":"jamalia.alnismith1@twigdad.xyz","to":"recatnap@example.com","date":"Apr 26, 2011","subject":"FW: Can you get DE to resubmit accounts?","folder":"Inbox"},{"id":6,"from":"lionel.qugy@cribsmoke.xyz","to":"recatnap@example.com","date":"May 22, 2011","subject":"RE: Catch up at 9:00 to finalise rain spec","folder":"Inbox"},{"id":7,"from":"Madison Lalinesson \u003cmelinda.gofagy@wing−language2.xyz\u003e","to":"recatnap@example.com","date":"May 19, 2011","subject":"RE: Pencil scenarios","folder":"Inbox"},{"id":8,"from":"rajah.nukripyford@cast92.xyz","to":"recatnap@example.com","date":"Apr 28, 2011","subject":"Flavor benefit gig","folder":"Inbox"},{"id":9,"from":"Sandra Juanhison \u003cyoshi.mostaline72@facefruit.xyz\u003e","to":"recatnap@example.com","date":"May 8, 2011","subject":"RE: Apparel5 network is back up","folder":"Inbox"},{"id":10,"from":"Sylvester \u003crose.va@bunpig98.xyz\u003e","to":"recatnap@example.com","date":"May 1, 2011","subject":"Feedback requested by Ayanna Nuyo","folder":"Inbox"},{"id":11,"from":"veronica@heart.xyz","to":"recatnap@example.com","date":"May 4, 2011","subject":"Project Book starting 6pm","folder":"Inbox"},{"id":12,"from":"XLN \u003cbasia@framehome.xyz\u003e","to":"recatnap@example.com","date":"May 8, 2011","subject":"RE: Remember Whoopi\u0027s joke","folder":"Inbox"}]}

chosenMailDataのJSONサンプル

{"id":1,"from":"Abbot \u003coliver@smoke−stage.xyz\u003e","to":"recatnap@example.com","date":"May 25, 2011","subject":"Booking confirmation #389629244","messageContent":"Hi!\u003cbr/\u003e\u003cbr/\u003eSchwebet und ernsten zu ich trane diesmal schatten ich folgenden erste seh jenem und irrt was menge dunst herauf. Jenem meinem die mich bang jenem den lebens das busen verklungen fuhlt folgenden. Stunden folgenden um nach widerklang strenge ein welt ich euch alten der um nun erfreuet gedrange. Festzuhalten bilder mich ihr jenem mit verklungen auf euch wird selbst des noch weich an des. Tranen um sehnen gleich das stunden irrt einst ertont besitze ein und liebe wohl noch manche und hinweggeschwunden ertont.\u003cbr/\u003e\u003cbr/\u003eLied lieb zauberhauch erste die steigen fuhlt mich liebe halbverklungnen zu selbst liebe gluck. Mir es fuhlt hinweggeschwunden schwebet nun euch gluck auf irrt neu weiten fuhlt und jenem bringt lebens versuch. Erste folgenden ich walten wird euren sang nicht lebt mit es steigt widerklang tonen nun busen.\u003cbr/\u003e\u003cbr/\u003eGesange zu nun hinweggeschwunden vom mich fuhlt trane blick kommt zu. Um wohl es freundliche denen geneigt wird. Menge horen zauberhauch vom ertont wiederholt mich die nicht jenem euch ein.\u003cbr/\u003e\u003cbr/\u003eWiderklang der lebens der zug trane selbst sich bilder alten strenge zerstoben zauberhauch die um. Ertont versuch erfreuet und. Ein wieder zerstreuet zerstoben folgt ich herzen der kommt ihr mein sich ersten gedrange.\u003cbr/\u003e\u003cbr/\u003eBest regards − Jonas","folder":"Inbox"}

新着(ニュース関連以外)

2017-11-09
PCでプッシュ通知ってのをしたい。
2017-11-06
PHPのバージョンを上げたらwikiが壊れたっぽい。
2017-08-03
formのinputでmaxlengthを使うとFirefoxでバグってた。他のブラウザでも気づかずにバグってたかもしれない。
2017-07-19
折れ線グラフをもう少しゆるやかに・・・というか何というか・・・調べていくと「移動平均」っていう言葉にたどり着いた
2017-07-10
FuelPHPの1.8をダウンロードして使っていたらセッションが使えないということに気付いた。