入力フィールドの増減操作結果をJSONで吸収する

先日書いた「jQuery で table の行追加と削除」は、単に .append の使い方のサンプルでしかない。
もっと現実的なサンプルを書いてみた。

ブラウザ側で入力フィールドを追加した場合を考慮して JSONhiddenフィールドにまとめて送信する方法

https://code.google.com/p/jquery-json/

を使うことになる。
ページの head は、以下のようにする。

<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="../js/jquery.json-2.4.min.js"></script>
<!-- このページ専用の JavaScript -->
<script type="text/javascript" src="../js/itemrequest.js"></script>

HTML サンプル

<div>
   <input type="text" id="add_item">
   <input type="button" value="追加" id="btn_add">
</div>
<br/>
<form id="form1">
<div>
   <table id="item-table" class="border-table">
      <thead>
         <tr>
            <th> 商 品 </th>
            <th> 数 量 </th>
            <th></th>
         </tr>
      </thead>
      <tbody>
         <tr>
            <td><input type="text" id="item1"  name="item1"  value="ロクシタン" ></td>
            <td><input type="text" id="count1" name="count1" value="1" class="in_amount"></td>
            <td><input type="button" value="削除" class="btn_del"></td>
         </tr>
         <tr>
            <td><input type="text" id="item2"  name="item2"  value="リードケース" ></td>
            <td><input type="text" id="count2" name="count2" value="2" class="in_amount"></td>
            <td><input type="button" value="削除" class="btn_del"></td>
         </tr>
         <tr>
            <td><input type="text" id="item3"  name="item3"  value="掃除用羽根" ></td>
            <td><input type="text" id="count3" name="count3" value="4" class="in_amount"></td>
            <td><input type="button" value="削除" class="btn_del"></td>
         </tr>
      </tbody>
   </table>
</div>
<br/>
</form>
<form id="form2" action="/itemrequest" method="post">
<div>
   <input type="hidden" name="jsondata" id="jsondata" value=''>
   <input type="submit" value="submit">
</div>
</form>
<hr/>
Debug
<div id="result">
   <input type="button" value="tojson" id="tojson">
   <br/>
   <textarea rows="10" cols="60" id="resultarea"></textarea>
</div>

ページのイメージ(デバッグの tojson を押した状態)

f:id:posturan:20160313192948j:plain



itemrequest.jsの内容
/* itemrequest.js
 */

$.fn.serializeObject = function(){
   var o = {};
   var a = this.serializeArray();
   $.each(a, function() {
      if (o[this.name] !== undefined) {
         if (!o[this.name].push) {
            o[this.name] = [o[this.name]];
         }
         o[this.name].push(this.value || '');
      }else{
         o[this.name] = this.value || '';
      }
   });
   return o;
};

var itemNo;
$(function(){
   itemNo = $("#item-table tbody tr").size() + 1;
   $("#btn_add").on("click", function(){
      $("#item-table").append(
         $("<tr></tr>")
         .append($("<td></td>").html("<input type=\"text\" name=\"item"+itemNo+"\" value=\""+$("#add_item").val()+"\">"))
         .append($("<td></td>").html("<input type=\"text\" name=\"count"+itemNo+"\" value=\"1\" class=\"in_amount\">"))
         .append($("<td></td>").html("<input type=\"button\" value=\"削除\" class=\"btn_del\">"))
      );
      itemNo++;
      // btn_del で削除の再設定
      setDeleteRow(".btn_del");
   });
   // btn_del で削除
   setDeleteRow(".btn_del");

   $("#form1").submit(function(){
      var data = $.toJSON($("#form1").serializeObject());
      $("#resultarea").text(data);
      $("#jsondata").val(data);
   });
   $("#tojson").on("click", function(){
      var data = $.toJSON($("#form1").serializeObject());
      $("#resultarea").text(data);
      $("#jsondata").val(data);
   });
});
function setDeleteRow(classname){
   $(classname).click(function(){
      var rowNum = $(this).parent().parent()[0].rowIndex;
      if (rowNum >= 0){
         $(this).parent().parent().remove();
      }
   });
}


この中で、以外と見落としやすいテクニックは入力フィールドの増減と、パラメータ Key になる name 属性名が重複が起きないように、
上記では、itemNo の変数スコープを工夫している。