HTMLでGridView部品のような表示・動作がしたい

投稿者: Anonymous

FirefoxアドオンをChrome拡張に移植中なんですが、Visual StudioなどにあるGUI、GridViewのような表示をしたくて悩んでます。具体的にどんなものかと言うと以下の画像のようなものです。
FirefoxアドオンのGrid
selectタグだと複数列ができません。
条件としては、

  1. 複数列表示ができる
  2. 行単位での選択・検知ができる

を満たすようなものです。

解決

HTML, CSS のみで質問文にあるような動作を実現することは難しいと思います。DataTablestabulator のようなテーブル生成を行う JavaScript ライブラリを用いることで、そのようなことが可能です。

たとえば、 tabulator を使用した場合は下記コードのようになります。tabulator では選択や選択解除時に rowSelectionChanged イベントが発生します。これは最初の引数として、選択された順序で各行のデータの配列を渡す[1]ため、「行単位での選択・検知」が行えます。

Row Selection Changed[1]

Whenever the number of selected rows changes, through selection or deselection, the rowSelectionChanged event is triggered. This passes an array of the data objects for each row in the order they were selected as the first argument, and an array of row components for each of the rows in order of selection as the second argument.

また、今回は tabulator の CSS を変更せずに使用していますが、このような装飾は各要素に割り当てられたクラスへ CSS を適用することで、独自にカスタマイズすることが出来ます[2]。通常のように CSS を記述することは難しいですが、これらのクラスや属性セレクタなどを組み合わせることで、期待通りの装飾を施すことも出来ると思います。

CSS Classes[2]

The tables below outline the key classes involved in styling Tabulator. You can include your own custom CSS after importing the library to customise its look and feel

_x000D_

_x000D_

const dayOfWeek = {
  "日": 0,
  "月": 1,
  "火": 2,
  "水": 3,
  "木": 4,
  "金": 5,
  "土": 6
};

const table = new Tabulator("#grid-view", {
  columns: [{
      title: "URL",
      field: "url",
    },
    {
      title: "タイトル",
      field: "title",
    },
    {
      title: "表示間隔",
      field: "rating",
      sorter: "number"
    },
    {
      title: "曜日",
      field: "day",
      sorter: (day1, day2) => (dayOfWeek[day1] - dayOfWeek[day2])
    },
    {
      title: "時刻",
      field: "time",
      sorter: "time"
    },
  ],
  cellVertAlign: "middle",
  height: "250px",
  layout: "fitColumns",
  selectable: true,
  rowSelectionChanged: function(data, rows) {
    $(".select-stats").text(`${data.length}個のデータを選択中`);
  },
});

const tabledata = [{
    id: 1,
    url: "https://foo.example.com/",
    title: "foo",
    rating: "6",
    day: "水",
    time: "7:00"
  },
  {
    id: 2,
    url: "https://hoge.example.com/",
    title: "hoge",
    rating: "12",
    day: "月",
    time: "9:00"
  },
  {
    id: 3,
    url: "https://bar.example.com/",
    title: "bar",
    rating: "3",
    day: "木",
    time: "19:00"
  },
  {
    id: 4,
    url: "https://fuga.example.com/",
    title: "fuga",
    rating: "50",
    day: "火",
    time: "2:00"
  },
  {
    id: 5,
    url: "https://piyo.example.com/",
    title: "piyo",
    rating: "25",
    day: "土",
    time: "21:00"
  },
];
table.setData(tabledata);

_x000D_

.tabulator-row .tabulator-cell {
  height: 5em;
}

_x000D_

<link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.7.2/css/tabulator.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.7.2/js/tabulator.min.js"></script>

<div id="grid-view"></div>
<div class="select-stats"></div>

_x000D_

_x000D_

_x000D_

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *