jQueryでリストを再帰処理.

javascriptであるリストを羅列したいときに,例えばページのフォーマットがA4用紙であるような場合にはリストが用紙(table1)をはみ出してしまうような場合に 次の用紙(table2)に羅列していく必要があります.それでもはみ出してしまうような場合はさらにtable3へ…とい行ったように入力によってどんどんページを増やして行かなくてはなりません.

その時には再帰関数を定義するとコードがスッキリするでしょう. 今回は以下のようなコードを書きました.


<script> // ページのロードが完了したら再帰関数の実行 $(document).ready(function(){ var page = 1; recall(page); }); // 再帰関数本体 function recall(page){ var is_over = overlist(page); if(is_over){ page++; recall(page); } } // リストが溢れているか判定する関数 function overlist(page){ var buttom_margin = 10; var card = $(".card"+page); var elements = $('.billing_item', card); var card_height = $('.card'+page).outerHeight(); var element_len = elements.length; var is_over = false; var over_list = []; for (var i=0; i<element_len; i++){ if(is_over){ over_list.push(elements[i]); } else { var top = $(elements[i]).position().top; var height = $(elements[i]).outerHeight(); if(top + height + buttom_margin > card_height){ is_over = true; page++; new_table(page); over_list.push(elements[i]); } } } // 溢れたリストがあれば次のページのテーブルにprepend $(".tbody" + page).prepend(over_list); return is_over } // 新しいページを作る関数 function new_table(page){ var element_card = $('#card-default').clone().removeAttr("id").addClass("card"+page); $("tbody",element_card).attr("class", "tbody"+page); $("section",element_card).attr("id", "section"+page); $(".card"+(page-1)).after(element_card); } </script>
<!-- Html 追加ページ用フォーマット -->
<div style="display:none">
  <div id="card-default">
    <section class="print_doc" id="section">
            <table>
              <thead">
              <tr>
                <th>No.</th>
                <th>品目</th>
                <th>数量</th>
                <th>単価</th>
                <th>価格</th>
              </tr>
              </thead>
              <tbody>
              </tbody>
            </table>
      </section>
  </div>
</div>

これらをうまく活用して組み込めばページ区切りのされたリストの表示ができます. このデフォルトのテーブルにあえて溢れるようなdatasのリストを表示させようとしても,再帰関数がリストがA4フォーマットからはみ出なくなるまでテーブルを複製し続けていきます.

    <section class="print_doc" id="section1">
            <table>
              <thead">
              <tr>
                <th>No.</th>
                <th>品目</th>
                <th>数量</th>
                <th>単価</th>
                <th>価格</th>
              </tr>
              </thead>
              <tbody class="tbody1">
                <?php foreach ($datas['billing_items'] as $i => $item): ?>
                <tr id = <?= $i ?>  >
                  <td><?= h($i + 1); ?></td>
                  <td><?= nl2br(h($item["item_name"])); ?></td>
                  <td><?= h(number_format($item["quantity"])); ?></td>
                  <td><?= h(number_format($item["price"])); ?></td>
                  <td><?= h(number_format($item["subtotal"])); ?>
                </td>
              </tr>
            <?php endforeach ?>
            </tbody>
            </table>
      </section>