formの入力と値のサンプル:必須入力ありで、ボタンの有効・無効

  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>formの入力と値のサンプル:必須入力ありで、ボタンの有効・無効</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.     ko.applyBindings(new ViewModel());
  11.   });
  12.   function ViewModel() {
  13.     var self = this;
  14.     // 品名データ
  15.     self.itemData = ko.observableArray([
  16.       {"name": "ねぎ間",         "price": "168"},
  17.       {"name": "ハツ",           "price": "136"},
  18.       {"name": "レバー",         "price": "136"},
  19.       {"name": "ぼんちり",       "price": "136"},
  20.       {"name": "はらみ",         "price": "136"},
  21.       {"name": "うずら玉子",     "price": "136"},
  22.       {"name": "なんこつ",       "price": "136"},
  23.       {"name": "手羽先",         "price": "168"},
  24.       {"name": "せせり",         "price": "136"},
  25.       {"name": "白レバー",       "price": "168"},
  26.       {"name": "丸ごとシマウマ", "price": "290"}
  27.     ]);
  28.     // 品名の初期値
  29.     self.selected = ko.observable(self.itemData()[10]);
  30.     // 注文内容
  31.     self.Order    = ko.observable();
  32.     self.Item     = ko.computed(function() { return self.selected().name; }, self);
  33.     self.Taste    = ko.observable();
  34.     self.perPrice    = ko.computed(function() { return self.selected().price; }, self);
  35.     self.KushiNum = ko.observable(1);
  36.     self.Price    = ko.computed(function()
  37.     {
  38.       kushi = 1;
  39.       if (isNaN(self.KushiNum()) != true && 0 < self.KushiNum())
  40.       {
  41.         kushi = parseFloat(self.KushiNum());
  42.       }
  43.       total = parseFloat(self.selected().price) * kushi;
  44.       return total;
  45.     }, self);
  46.     
  47.     // 必須入力のフラグ:値が無問題なら「0」
  48.     self.numOrder = ko.observable(0);
  49.     self.numTaste = ko.observable(0);
  50.     self.numNum   = ko.observable(0);
  51.     // 注文者チェック:入力なければ警告表示
  52.     self.waringOrder = ko.computed(function()
  53.     {
  54.       waringOrderMsg = "";
  55.       if (self.Order() == "" || self.Order() == undefined) 
  56.       {
  57.         waringOrderMsg = "※必須入力";
  58.         self.numOrder(1);
  59.       }
  60.       else
  61.       {
  62.         self.numOrder(0);
  63.       }
  64.       
  65.       return waringOrderMsg;
  66.     }, self);
  67.     // 味チェック:入力なければ警告表示
  68.     self.waringTaste = ko.computed(function()
  69.     {
  70.       waringTasteMsg = "";
  71.       if (self.Taste() == "" || self.Taste() == undefined) 
  72.       {
  73.         waringTasteMsg = "※必須入力";
  74.         self.numTaste(1);
  75.       }
  76.       else
  77.       {
  78.         self.numTaste(0);
  79.       }
  80.       
  81.       return waringTasteMsg;
  82.     }, self);
  83.     // 本数チェック:数字じゃない・1本未満ならば警告表示
  84.     self.waringNum = ko.computed(function()
  85.     {
  86.       waringNumMsg = "";
  87.       if (isNaN(self.KushiNum()) == true)
  88.       {
  89.         waringNumMsg = "※数字だけ";
  90.         self.numNum(1);
  91.       }
  92.       else if (parseFloat(self.KushiNum()) < 1)
  93.       {
  94.         waringNumMsg = "※1本以上";
  95.         self.numNum(1);
  96.       }
  97.       else if (self.KushiNum() == "")
  98.       {
  99.         waringNumMsg = "※必須入力";
  100.         self.numNum(1);
  101.       }
  102.       else
  103.       {
  104.         self.numNum(0);
  105.       }
  106.       
  107.       return waringNumMsg;
  108.     }, self);
  109.     // ボタンの有効化:必須対象の合計が「0」じゃないなら「無効」
  110.     self.sendBtn = ko.computed(function()
  111.     {
  112.       numTotal = self.numOrder() + self.numTaste() + self.numNum();
  113.       return numTotal;
  114.     }, self);
  115.     // オーダーボタンが押されたとき
  116.     self.gotoOrder = function()
  117.     {
  118.       msg = "";
  119.       msg += "注文者:" + this.Order()    + "\n";
  120.       msg += "商品名:" + this.Item()     + "\n";
  121.       msg += " 味 :" + this.Taste()    + "\n";
  122.       msg += "単 価:" + this.perPrice() + "円\n";
  123.       msg += "本 数:" + this.KushiNum() + "本\n";
  124.       msg += "合 計:" + this.Price()    + "円\n";
  125.       alert(msg);
  126.     }
  127.   }
  128. </script>
  129. <style>
  130.   table
  131.   {
  132.     border-collapse:collapse;
  133.     margin:0;
  134.   }
  135.   th, td
  136.   {
  137.     text-align:left;
  138.     vertical-align:top;
  139.     padding:8px;
  140.     font-weight:normal;
  141.     border:1px solid #ccc;
  142.   }
  143.   th
  144.   {
  145.     background:#f3f3f3;
  146.   }
  147. </style>
  148. </head>
  149. <body>
  150. <h1>formの入力と値のサンプル:必須入力ありで、ボタンの有効・無効</h1>
  151. <table>
  152. <tr><th>注文者</th><td>
  153.   <input type="text" data-bind="value: Order, valueUpdate: 'afterkeydown'" />
  154.   <span style="color:red;" data-bind="text: waringOrder, visible: waringOrder"></span>
  155. </td></tr>
  156. <tr><th>商品</th><td><select data-bind="options: itemData, optionsText: 'name', value: selected"></select></td></tr>
  157. <tr><th>味</th><td>
  158.   <label><input type="radio" name="tasteGroup" data-bind="checked: Taste" value="たれ" />たれ</label> /
  159.   <label><input type="radio" name="tasteGroup" data-bind="checked: Taste" value="塩" />塩</label> /
  160.   <label><input type="radio" name="tasteGroup" data-bind="checked: Taste" value="味噌" />味噌</label> /
  161.   <label><input type="radio" name="tasteGroup" data-bind="checked: Taste" value="明太子" />明太子</label> /
  162.   <label><input type="radio" name="tasteGroup" data-bind="checked: Taste" value="ネギマヨ" />ネギマヨ</label>
  163.   <span style="color:red;" data-bind="text: waringTaste, visible: waringTaste"></span>
  164. </td></tr>
  165. <tr><th>本数</th><td>
  166.   <input type="text" data-bind="value: KushiNum, valueUpdate: 'afterkeydown'" /> 本
  167.   <span style="color:red;" data-bind="text: waringNum, visible: waringNum"></span>
  168. </td></tr>
  169. <tr><th>価格</th><td><span data-bind="text: Price"></span> 円(単価:<span data-bind="text: perPrice"></span> 円)</td></tr>
  170. </table>
  171. <div style="margin-top:6px;"><input type="submit" data-bind="click: gotoOrder, disable: sendBtn" value="注文" /></div>
  172. <div style="font-size:10pt;text-align:right;margin-top:0.5em;">
  173. <a href="//tips.recatnap.info/" target="_top">PCスキルの小技・忘却防止メモ</a> -
  174. <a href="//tips.recatnap.info/wiki/" target="_top">PCスキルの小技・忘却防止メモのまとめ(wiki)</a>
  175. </div>
  176. <div style="font-size:10pt;text-align:center;margin-top:0.5em;padding:0.5em;border-top:1px solid #ccc;">
  177. Copyright &copy; 2009 by PCスキルの小技・忘却防止メモ. All rights reserved.
  178. </div>
  179. </body>
  180. </html>