knockout.jsで親ウィンドウに値を渡す:子で追加ボタンが押されたとき表示:改

  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>knockout.jsで親ウィンドウに値を渡す:子で追加ボタンが押されたとき表示:改</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. <style type="text/css">
  9. td, th
  10. {
  11.   border:1px solid #ccc;
  12. }
  13. .switchArea
  14. {
  15.   border:1px dotted #ccc;
  16.   background:#f3f3f3;
  17.   padding:6px;
  18.   margin-top:6px;
  19. }
  20. .checkBtnArea
  21. {
  22.   display:none;
  23. }
  24. .checkBtnArea.switchArea
  25. {
  26.   display:block;
  27. }
  28. </style>
  29. <script type="text/javascript">
  30.   $(document).ready(function () {
  31.     ko.applyBindings(new ViewModel());
  32.   });
  33.   function ViewModel() {
  34.     var self = this;
  35.     self.jsonTemporary = {};
  36.     self.jsonData = ko.observable();
  37.     self.tempTaste = ko.observable();
  38.     this.viewTaste = ko.computed( function()
  39.     {
  40.       return self.tempTaste();
  41.     }, this);
  42.     // 表示
  43.     self.GotoView = function(json) {
  44.       this.jsonData(json);
  45.     };
  46.     // 指定ボタンが押されたとき
  47.     self.gotoTaste = function(data, event) {
  48.       htmlDom = event.target;
  49.       $(htmlDom).parents("tr").find(".checkBtnArea").removeClass("switchArea");
  50.       
  51.       url = "043_passing_value_child.html";
  52.       window.open(url, "window_name", "width=250,height=350,scrollbars=yes,resizable=yes,status=yes");
  53.     };
  54.     // 登録
  55.     self.entryTaste = function(data, event) {
  56.       // 確認枠の内容をデータにコピー
  57.       htmlDom = event.target;
  58.       this.taste = $(htmlDom).parents("tr").find(".checkDiv")[0].textContent;
  59.       
  60.       // セル「味」のトコに表示させる
  61.       self.tempTaste(this.taste);
  62.       
  63.       // 確認枠と「確定」「キャンセル」ボタンを非表示にする
  64.       visibleCheckArea();
  65.     };
  66.     // キャンセル
  67.     self.cancelTaste = function(data, event) {
  68.       // 確認枠と「確定」「キャンセル」ボタンを非表示にする
  69.       visibleCheckArea();
  70.     };
  71.     // 削除
  72.     self.deleteTaste = function(data, event) {
  73.       // データから削除
  74.       this.taste = "";
  75.       
  76.       // セル「味」のトコを非表示にする
  77.       self.tempTaste(this.taste);
  78.       
  79.       // 確認枠と「確定」「キャンセル」ボタンを非表示にする
  80.       visibleCheckArea();
  81.     };
  82.     // デフォルトでの表示:元データを読込んでおく
  83.     $.getJSON("./testdata/testdataA.txt", {}, function(json){
  84.       json["taste"] = "";
  85.       self.jsonTemporary = json; // 何回も読込みされるのがイヤなので保管しておく
  86.       self.GotoView(self.jsonTemporary);
  87.     });
  88.   }
  89.   // 確認用枠を非表示
  90.   function visibleCheckArea()
  91.   {
  92.     $(".checkBtnArea").removeClass("switchArea");
  93.     $(".checkDiv").html("");
  94.   }
  95. </script>
  96. </head>
  97. <body>
  98. <h1>「knockout.jsで親ウィンドウに値を渡す」の親ウィンドウ側:子で追加ボタンが押されたとき表示:改</h1>
  99. <p>「表示のON・OFF」を「styleの追加・削除」から「class名の追加・削除」に変更(css側でまとめてスタイル設定ができる)</p>
  100. <div>
  101.   <table data-bind="visible: jsonData()">
  102.     <thead><tr><th>品名</th><th>金額</th><th>味</th><th>ボタン</th></thead>
  103.     <tbody data-bind="with: jsonData">
  104.       <tr>
  105.         <td data-bind="text: name"></td>
  106.         <td data-bind="text: price"></td>
  107.         <td data-bind="text: $root.viewTaste"></td>
  108.         <td>
  109.           <button data-bind="click: $root.gotoTaste">味を指定・変更</button>
  110.           <button data-bind="click: $root.deleteTaste">削除</button>
  111.           <br />
  112.           <div class="checkBtnArea">
  113.             <div class="checkDiv"></div>
  114.             <button data-bind="click: $root.entryTaste">確定</button>
  115.             <button data-bind="click: $root.cancelTaste">キャンセル</button>
  116.           </div>
  117.         </td>
  118.       </tr>
  119.     </tbody>
  120.   </table>
  121. </div>
  122. <p>できれば…確定ボタンを押さずに即反映ってしたい。他のライブラリをひっぱってくればできそうだけど面倒そうなので挫折。</p>
  123. <hr>
  124. ちなみに子ウィンドウのHTMLソースは下記。
  125. <div style="border:1px solid #ccc;margin-top:1em;padding:0.5em;">
  126. <pre style="margin:0;">
  127. &lt;!DOCTYPE html>
  128. &lt;html lang="ja">
  129. &lt;head>
  130. &lt;meta charset="UTF-8">
  131. &lt;title>knockout.jsで親ウィンドウに値を渡す:子ウィンドウ&lt;/title>
  132. &lt;script type="text/javascript" src="jquery-1.5.1.min.js">&lt;/script>
  133. &lt;script type="text/javascript" src="knockout-2.1.0beta.js">&lt;/script>
  134. &lt;script type="text/javascript">
  135.   $(document).ready(function () {
  136.     ko.applyBindings(new ViewModelChild());
  137.   });
  138.   function ViewModelChild() {
  139.     var self = this;
  140.     self.clearBtn = ko.observable(false);
  141.     self.tasteAry = ko.observableArray([
  142.       {tasteData: 'たれ'}, {tasteData: '塩'}, {tasteData: '味噌'}, {tasteData: '芥子'},
  143.     ]);
  144.     // 追加ボタンが押されたとき
  145.     self.addTaste = function(data) {
  146.       source = "";
  147.       source += '&lt;div style="font-weight:bold;padding:3px; ">';
  148.       source += data.tasteData;
  149.       source += '&lt;/div>';
  150.       window.opener.$(".checkDiv").html(source);
  151.       window.opener.$(".checkBtnArea").addClass("switchArea");
  152.       
  153.       // クリアボタンを表示
  154.       self.clearBtn(true);
  155.     };
  156.     
  157.     // クリアボタンが押されたとき
  158.     self.clearTaste = function(data) {
  159.       window.opener.$(".checkDiv").html("");
  160.       window.opener.$(".checkBtnArea").removeClass("switchArea");
  161.       
  162.       // クリアボタンを非表示
  163.       self.clearBtn(false);
  164.     };
  165.   }
  166. &lt;/script>
  167. &lt;/head>
  168. &lt;body>
  169. &lt;h1>「knockout.jsで親ウィンドウに値を渡す」の子ウィンドウ側&lt;/h1>
  170. &lt;div>
  171.   &lt;div data-bind="visible: clearBtn" style="border:1px solid #ccc;text-align:center;padding:8px 0;">
  172.   &lt;button data-bind="click: $root.clearTaste">追加したものをクリア&lt;/buuton>&lt;br />
  173.   &lt;/div>
  174.   &lt;table data-bind="visible: tasteAry">
  175.     &lt;thead>&lt;tr>&lt;th>味&lt;/th>&lt;th>追加&lt;/th>&lt;/thead>
  176.     &lt;tbody data-bind="foreach: tasteAry">
  177.       &lt;tr>
  178.         &lt;td>&lt;button data-bind="click: $root.addTaste">追加&lt;/button>&lt;/td>
  179.         &lt;td data-bind="text: tasteData">&lt;/td>
  180.       &lt;/tr>
  181.     &lt;/tbody>
  182.   &lt;/table>
  183. &lt;/div>
  184. &lt;/body>
  185. &lt;/html>
  186. </pre>
  187. </div>
  188. <div style="font-size:10pt;text-align:right;margin-top:0.5em;">
  189. <a href="//tips.recatnap.info/" target="_top">PCスキルの小技・忘却防止メモ</a> -
  190. <a href="//tips.recatnap.info/wiki/" target="_top">PCスキルの小技・忘却防止メモのまとめ(wiki)</a>
  191. </div>
  192. <div style="font-size:10pt;text-align:center;margin-top:0.5em;padding:0.5em;border-top:1px solid #ccc;">
  193. Copyright &copy; 2009 by PCスキルの小技・忘却防止メモ. All rights reserved.
  194. </div>
  195. </body>
  196. </html>