knockoutjsちゅーとりある:データ件数によって処理を変える

  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>knockoutjsちゅーとりある:データ件数によって処理を変える</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. <script type="text/javascript">
  9.   $(document).ready(function () {
  10.     // 表示部
  11.     function SeatReservation(name, initialMeal) {
  12.       var self = this;
  13.       // data-bindの各ラベル?に対応する値の設定
  14.       self.name = name;
  15.       self.meal = ko.observable(initialMeal);
  16.       // 「price」がfalseの時は「None」と表示させる
  17.       self.formattedPrice = ko.computed(function() {
  18.         var price = self.meal().price;
  19.         return price ? "$" + price.toFixed(2) : "None";
  20.       });  
  21.     }
  22.     // ko.applyBindings()が呼ばれたときに実行される
  23.     function ReservationsViewModel() {
  24.       var self = this;
  25.       // データ
  26.       self.availableMeals = [
  27.         { mealName: "Standard (sandwich)", price: 0 },
  28.         { mealName: "Premium (lobster)", price: 34.95 },
  29.         { mealName: "Ultimate (whole zebra)", price: 290 }
  30.       ];
  31.       // 最初に表示するデータ(<table>の<tbody>のdata-bindのラベル?が「seats」の中身)
  32.       self.seats = ko.observableArray([
  33.         new SeatReservation("Steve", self.availableMeals[0]),
  34.         new SeatReservation("Bert", self.availableMeals[0])
  35.       ]);
  36.       // Priceの総額 
  37.       self.totalSurcharge = ko.computed(function() {
  38.         var total = 0;
  39.         for (var i = 0; i < self.seats().length; i++)
  40.         {
  41.           total += self.seats()[i].meal().price;
  42.         }
  43.         return total;
  44.       });  
  45.       // 「Reserve another seat」をクリックしたときpush()する
  46.       self.addSeat = function() {
  47.         self.seats.push(new SeatReservation("", self.availableMeals[0]));
  48.       }
  49.       
  50.       // 「Remove」をクリックしたときremove()する
  51.       self.removeSeat = function(seat) {
  52.         self.seats.remove(seat)
  53.       }
  54.       
  55.     }
  56.     ko.applyBindings(new ReservationsViewModel());
  57.   })();
  58. </script>
  59. </head>
  60. <body>
  61. <h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>
  62. <table>
  63. <thead><tr>
  64.   <th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
  65. </tr></thead>
  66. <tbody data-bind="foreach: seats">
  67. <tr>
  68.   <td><input data-bind="value: name" /></td>
  69.   <td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
  70.   <td data-bind="text: formattedPrice"></td>
  71.   <td><a href="#" data-bind="click: $root.removeSeat">Remove</a></td>
  72. </tr>
  73. </tbody>
  74. </table>
  75. <button data-bind="click: addSeat, enable: seats().length < 5">Reserve another seat</button>
  76. <h3 data-bind="visible: totalSurcharge() > 0">
  77.   Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
  78. </h3>
  79. <div style="font-size:10pt;text-align:right;margin-top:0.5em;">
  80. <a href="//tips.recatnap.info/" target="_top">PCスキルの小技・忘却防止メモ</a> -
  81. <a href="//tips.recatnap.info/wiki/" target="_top">PCスキルの小技・忘却防止メモのまとめ(wiki)</a>
  82. </div>
  83. <div style="font-size:10pt;text-align:center;margin-top:0.5em;padding:0.5em;border-top:1px solid #ccc;">
  84. Copyright &copy; 2009 by PCスキルの小技・忘却防止メモ. All rights reserved.
  85. </div>
  86. </body>
  87. </html>