0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

フレームワーク無しHTMLテーブルをBootstrapで再現する場合

Last updated at Posted at 2021-09-17

過去に作ったフレームワーク無しのHTMLテーブルを、Bootstrap(5)で再現しようとすると、
過去、手抜き、つまりborder-bottom: noneなどで罫線を消してセル結合っぽくしている場合、
(HTML的にはダメですが、ループを回してDBを表示する場合めんどくさくてつい…)
融通がきかなくて困る場合があります(した)。

##こういうテーブルです
テーブルサンプル.png

##手抜きをBootstrapで再現
###HTML

  • 罫線無しのテーブル(table-borderless)にして、個別にborderを設定する
  • 同列の前行が違う値だったら、border-topを追加設定する
<div class="table-responsive">
  <table class="table table-borderless">
    <thead class="text-center table-light">
      <tr>
        <th scope="col" class="border-start border-top" nowrap>部名</th>
        <th scope="col" class="border-start border-top" nowrap>部長</th>
        <th scope="col" class="border-start border-top" nowrap>課名</th>
        <th scope="col" class="border-start border-top" nowrap>課長</th>
        <th scope="col" class="border-start border-top" nowrap>ユニット名</th>
        <th scope="col" class="border-start border-top" nowrap>ユニット<br>リーダー</th>
        <th scope="col" class="border-start border-end border-top" nowrap>メンバー</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="border-start border-top" nowrap>何でも部</td>
        <td class="border-start border-top" nowrap>部長 太郎</td>
        <td class="border-start border-top" nowrap>課1</td>
        <td class="border-start border-top" nowrap>課長 太郎</td>
        <td class="border-start border-top" nowrap>ユニット1</td>
        <td class="border-start border-top" nowrap>ユニット 太郎</td>
        <td class="border-start border-end border-top" nowrap>メンバー 太郎</td>
      </tr>
      <tr>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start border-end" nowrap>メンバー 次郎</td>
      </tr>
      <tr>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start border-top" nowrap>ユニット2</td>
        <td class="border-start border-top" nowrap>ユニット 次郎</td>
        <td class="border-start border-end  border-top" nowrap>メンバー 三郎</td>
      </tr>
      <tr>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-end border-bottom" nowrap>メンバー 四郎</td>
      </tr>
      <tr>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start border-top" nowrap>課2</td>
        <td class="border-start border-top" nowrap>課長 次郎</td>
        <td class="border-start border-top" nowrap>ユニット1</td>
        <td class="border-start border-top" nowrap>ユニット 三郎</td>
        <td class="border-start border-end border-top" nowrap>メンバー 五郎</td>
      </tr>
      <tr>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start border-end" nowrap>メンバー 六郎</td>
      </tr>
      <tr>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start" nowrap></td>
        <td class="border-start border-top" nowrap>ユニット2</td>
        <td class="border-start border-top" nowrap>ユニット 四郎</td>
        <td class="border-start border-end  border-top" nowrap>メンバー 七郎</td>
      </tr>
      <tr>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-bottom" nowrap></td>
        <td class="border-start border-end border-bottom" nowrap>メンバー 八郎</td>
      </tr>
    </tbody>
  </table>
</div><!-- .table-responsive -->

###PHP

<?php
$data[0] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット1", "ユニット 太郎", "メンバー 太郎");
$data[1] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット1", "ユニット 太郎", "メンバー 次郎");
$data[2] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット2", "ユニット 次郎", "メンバー 三郎");
$data[3] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット2", "ユニット 次郎", "メンバー 四郎");
$data[4] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット1", "ユニット 三郎", "メンバー 五郎");
$data[5] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット1", "ユニット 三郎", "メンバー 六郎");
$data[6] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット2", "ユニット 四郎", "メンバー 七郎");
$data[7] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット2", "ユニット 四郎", "メンバー 八郎");
?>
<div class="table-responsive">
  <table class="table table-borderless">
    <thead class="text-center table-light">
      <tr>
        <th scope="col" class="border-start border-top" nowrap>部名</th>
        <th scope="col" class="border-start border-top" nowrap>部長</th>
        <th scope="col" class="border-start border-top" nowrap>課名</th>
        <th scope="col" class="border-start border-top" nowrap>課長</th>
        <th scope="col" class="border-start border-top" nowrap>ユニット名</th>
        <th scope="col" class="border-start border-top" nowrap>ユニット<br>リーダー</th>
        <th scope="col" class="border-start border-end border-top" nowrap>メンバー</th>
      </tr>
    </thead>
    <tbody>
<?php
$i = 0;
while($i < count($data)){
    echo "      <tr>\n";
    //先頭行
    if ($i == 0) {
        echo "        <td class=\"border-start border-top\" nowrap>{$data[$i]{0}}</td>\n";
        echo "        <td class=\"border-start border-top\" nowrap>{$data[$i]{1}}</td>\n";
        echo "        <td class=\"border-start border-top\" nowrap>{$data[$i]{2}}</td>\n";
        echo "        <td class=\"border-start border-top\" nowrap>{$data[$i]{3}}</td>\n";
        echo "        <td class=\"border-start border-top\" nowrap>{$data[$i]{4}}</td>\n";
        echo "        <td class=\"border-start border-top\" nowrap>{$data[$i]{5}}</td>\n";
        echo "        <td class=\"border-start border-end border-top\" nowrap>{$data[$i]{6}}</td>\n";
    } else {
        //先頭行後
        $j = 0;
        while($j <= 6){
            //上罫線
            $borderTop = " border-top";
            //表示データ
            $val = $data[$i][$j];
            //同列の前行と値が一致したら上罫線と値は表示しない
            if ($data[$i]{$j} == $data[$i - 1]{$j}) {
                $borderTop = "";
                $val = "";
            }
            //右罫線
            //最終列のみ右罫線表示
            $borderEnd = "";
            if ($j == 6) {
                $borderEnd = " border-end";
            }
            //下罫線
            //最終行のみ下罫線表示
            $borderBottom = "";
            if ($i == count($data) - 1) {
                $borderBottom = " border-bottom";
            }
            echo "        <td class=\"border-start{$borderEnd}{$borderTop}{$borderBottom}\" nowrap>{$val}</td>\n";
            $j++;
        }
    }
    echo "      </tr>\n";
    $i++;
}
?>
    </tbody>
  </table>
</div><!-- .table-responsive -->

##HTML的に正しいやり方
###HTML

  • 罫線有りのテーブル(table-bordered)にして、同じ値の場合はセルを結合する
<div class="table-responsive">
  <table class="table table-bordered">
    <thead class="text-center table-light">
      <tr>
        <th scope="col" nowrap>部名</th>
        <th scope="col" nowrap>部長</th>
        <th scope="col" nowrap>課名</th>
        <th scope="col" nowrap>課長</th>
        <th scope="col" nowrap>ユニット名</th>
        <th scope="col" nowrap>ユニット<br>リーダー</th>
        <th scope="col" nowrap>メンバー</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td nowrap rowspan="8">何でも部</td>
        <td nowrap rowspan="8">部長 太郎</td>
        <td nowrap rowspan="4">課1</td>
        <td nowrap rowspan="4">課長 太郎</td>
        <td nowrap rowspan="2">ユニット1</td>
        <td nowrap rowspan="2">ユニット 太郎</td>
        <td  nowrap>メンバー 太郎</td>
      </tr>
      <tr>
        <td nowrap>メンバー 次郎</td>
      </tr>
      <tr>
        <td nowrap rowspan="2">ユニット2</td>
        <td nowrap rowspan="2">ユニット 次郎</td>
        <td nowrap>メンバー 三郎</td>
      </tr>
      <tr>
        <td nowrap>メンバー 四郎</td>
      </tr>
      <tr>
        <td nowrap rowspan="7">課2</td>
        <td nowrap rowspan="7">課長 次郎</td>
        <td nowrap rowspan="2">ユニット1</td>
        <td nowrap rowspan="2">ユニット 三郎</td>
        <td nowrap>メンバー 五郎</td>
      </tr>
      <tr>
        <td nowrap>メンバー 六郎</td>
      </tr>
      <tr>
        <td nowrap rowspan="2">ユニット2</td>
        <td nowrap rowspan="2">ユニット 四郎</td>
        <td nowrap>メンバー 七郎</td>
      </tr>
      <tr>
        <td nowrap>メンバー 八郎</td>
      </tr>
    </tbody>
  </table>
</div><!-- .table-responsive -->

###PHP

  • 同列の前行と違う値だったら(同じ値だったら何も表示しない)
  • 内部に別ループを回し、同列の次行と違う値になるまでループを回し、結合数(rowspan)をカウント
  • rowspanに結合数を設定
<?php
$data[0] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット1", "ユニット 太郎", "メンバー 太郎");
$data[1] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット1", "ユニット 太郎", "メンバー 次郎");
$data[2] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット2", "ユニット 次郎", "メンバー 三郎");
$data[3] = array("何でも部", "部長 太郎", "課1", "課長 太郎", "ユニット2", "ユニット 次郎", "メンバー 四郎");
$data[4] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット1", "ユニット 三郎", "メンバー 五郎");
$data[5] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット1", "ユニット 三郎", "メンバー 六郎");
$data[6] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット2", "ユニット 四郎", "メンバー 七郎");
$data[7] = array("何でも部", "部長 太郎", "課2", "課長 次郎", "ユニット2", "ユニット 四郎", "メンバー 八郎");
?>
<div class="table-responsive">
  <table class="table table-bordered">
    <thead class="text-center table-light">
      <tr>
        <th scope="col" class="border-start border-top" nowrap>部名</th>
        <th scope="col" class="border-start border-top" nowrap>部長</th>
        <th scope="col" class="border-start border-top" nowrap>課名</th>
        <th scope="col" class="border-start border-top" nowrap>課長</th>
        <th scope="col" class="border-start border-top" nowrap>ユニット名</th>
        <th scope="col" class="border-start border-top" nowrap>ユニット<br>リーダー</th>
        <th scope="col" class="border-start border-end border-top" nowrap>メンバー</th>
      </tr>
    </thead>
    <tbody>
<?php
$i = 0;
while($i < count($data)){
    echo "      <tr>\n";
    //先頭行
    if ($i == 0) {
        $j = 0;
        while($j <= 6){
            //表示データ
            $val = $data[$i][$j];
            //同列の次行と値が一致したら
            if ($data[$i]{$j} == $data[$i + 1]{$j}) {
                //結合数
                $r = 1;
                //現行から開始
                $n = $i;
                while($n < count($data) - 1){
                    if ($data[$i]{$j} == $data[$n + 1]{$j}) {
                        $r++;
                    } else {
                        break;
                    }
                    $n++;
                }
                echo "        <td rowspan=\"{$r}\" nowrap>{$val}</td>\n";
            } else {
                //以外は値のみ表示
                echo "        <td nowrap>{$val}</td>\n";
            }
            $j++;
        }
    } else {
        //先頭行後
        $j = 0;
        while($j <= 6){
            //表示データ
            $val = $data[$i][$j];
            //同列の前行と値が一致しなかったら(一致したら何も表示しない)
            if ($data[$i]{$j} != $data[$i - 1]{$j}) {
                //結合数
                $r = 1;
                //現行から開始
                $n = $i;
                while($n < count($data) - 1){
                    if ($data[$i]{$j} == $data[$n + 1]{$j}) {
                        $r++;
                    } else {
                        break;
                    }
                    $n++;
                }
                echo "        <td rowspan=\"{$r}\" nowrap>{$val}</td>\n";
            }
            $j++;
        }
    }
    echo "      </tr>\n";
    $i++;
}
?>
    </tbody>
  </table>
</div><!-- .table-responsive -->
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?