jQuery プラグイン DataTables のページネーションカスタマイズの方法

DataTables

HTMLで表を利用するとき、jQueryのプラグインであるDataTablesを利用すると、より多彩な表現をすることができるので、利用している方も多いと思います。

その中でも、テーブル設定を変更するだけで簡単にページネーションの機能を実装できるのは、プログラマーにとって非常にありがたいです。
しかも標準で9種類の表現ができ、基本的にはこれで困ることはないでしょう。

https://datatables.net/plug-ins/pagination/

しかしクライアントの要望により、これら標準ではない表現をする場合どうすればいいのでしょうか。実はDataTablesではこのページネーションをカスタマイズすることができます。
今回はそのDataTables ページネーションのカスタマイズ方法を紹介したいと思います。

利用可能なパーツ

DataTables 標準のページネーションには次の9種類があり、 pagetype を変更するだけで切り替えることができます。
ここで利用されているパーツに注目しましょう。ページネーションには5つのパーツが利用されています。

  • first … 先頭へ移動
  • previous … 前へ移動
  • ページ数 (ページ数内で "ellipsis" を指定すると「...」と表示)
  • next … 次へ移動
  • last … 最後へ移動

カスタマイズするときも、これらのパーツが利用可能です。

ページネーションのカスタマイズ

それで pagetype に新しく custom を追加しましょう。
新しく作るページネーションの仕様は、次のような内容にします。

  1. previous, next, ページ数の3つを利用し、ページ数のボタンは3つとする
  2. previous, next が有効でないときは、それを表示しない
  3. previous, next はシンプルにそれぞれ ≪, ≫ と表示する

それでは具体的にソースコードを示します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Country Code</title>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.css">
</head>
<body>
<table id="table_id" class="display">
    <thead><tr><th>Name</th><th>Code</th></tr></thead>
    <tbody></tbody>
</table>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.js"></script>
<script type="text/javascript">
    //テーブルに表示するデータ
    var data = [['Iceland', 'ISL'],['Ireland', 'IRL'],['Azerbaijan', 'AZE'],['Afghanistan', 'AFG'],['United States of America', 'USA'],['Virgin Islands (U.S.)', 'VIR'],['American Samoa', 'ASM'],['United Arab Emirates', 'ARE'],['Algeria', 'DZA'],['Argentina', 'ARG'],['Aruba', 'ABW'],['Albania', 'ALB'],['Armenia', 'ARM'],['Anguilla', 'AIA'],['Angola', 'AGO'],['Antigua and Barbuda', 'ATG'],['Andorra', 'AND'],['Yemen', 'YEM'],['United Kingdom of Great Britain and Northern Ireland', 'GBR'],['British Indian Ocean Territory', 'IOT'],['Virgin Islands (British)', 'VGB'],['Israel', 'ISR'],['Italy', 'ITA'],['Iraq', 'IRQ'],['Iran (Islamic Republic of)', 'IRN'],['India', 'IND'],['Indonesia', 'IDN'],['Wallis and Futuna', 'WLF'],['Uganda', 'UGA'],['Ukraine', 'UKR'],['Uzbekistan', 'UZB'],['Uruguay', 'URY'],['Ecuador', 'ECU'],['Egypt', 'EGY'],['Estonia', 'EST'],['Eswatini', 'SWZ'],['Ethiopia', 'ETH'],['Eritrea', 'ERI'],['El Salvador', 'SLV'],['Australia', 'AUS'],['Austria', 'AUT'],['Åland Islands', 'ALA'],['Oman', 'OMN'],['Netherlands', 'NLD'],['Ghana', 'GHA'],['Cabo Verde', 'CPV'],['Guernsey', 'GGY'],['Guyana', 'GUY'],['Kazakhstan', 'KAZ'],['Qatar', 'QAT'],['United States Minor Outlying Islands', 'UMI'],['Canada', 'CAN'],['Gabon', 'GAB'],['Cameroon', 'CMR'],['Gambia', 'GMB'],['Cambodia', 'KHM'],['North Macedonia', 'MKD'],['Northern Mariana Islands', 'MNP'],['Guinea', 'GIN'],['Guinea-Bissau', 'GNB'],['Cyprus', 'CYP'],['Cuba', 'CUB'],['Curaçao', 'CUW'],['Greece', 'GRC'],['Kiribati', 'KIR'],['Kyrgyzstan', 'KGZ'],['Guatemala', 'GTM'],['Guadeloupe', 'GLP'],['Guam', 'GUM'],['Kuwait', 'KWT'],['Cook Islands', 'COK'],['Greenland', 'GRL'],['Christmas Island', 'CXR'],['Grenada', 'GRD'],['Croatia', 'HRV'],['Cayman Islands', 'CYM'],['Kenya', 'KEN'],['Côte d\'Ivoire', 'CIV'],['Cocos (Keeling) Islands', 'CCK'],['Costa Rica', 'CRI'],['Comoros', 'COM'],['Colombia', 'COL'],['Congo', 'COG'],['Congo, Democratic Republic of the', 'COD'],['Saudi Arabia', 'SAU'],['South Georgia and the South Sandwich Islands', 'SGS'],['Samoa', 'WSM'],['Sao Tome and Principe', 'STP'],['Saint Barthélemy', 'BLM'],['Zambia', 'ZMB'],['Saint Pierre and Miquelon', 'SPM'],['San Marino', 'SMR'],['Saint Martin (French part)', 'MAF'],['Sierra Leone', 'SLE'],['Djibouti', 'DJI'],['Gibraltar', 'GIB'],['Jersey', 'JEY'],['Jamaica', 'JAM'],['Georgia', 'GEO'],['Syrian Arab Republic', 'SYR'],['Singapore', 'SGP'],['Sint Maarten (Dutch part)', 'SXM'],['Zimbabwe', 'ZWE'],['Switzerland', 'CHE'],['Sweden', 'SWE'],['Sudan', 'SDN'],['Svalbard and Jan Mayen', 'SJM'],['Spain', 'ESP'],['Suriname', 'SUR'],['Sri Lanka', 'LKA'],['Slovakia', 'SVK'],['Slovenia', 'SVN'],['Seychelles', 'SYC'],['Equatorial Guinea', 'GNQ'],['Senegal', 'SEN'],['Serbia', 'SRB'],['Saint Kitts and Nevis', 'KNA'],['Saint Vincent and the Grenadines', 'VCT'],['Saint Helena, Ascension and Tristan da Cunha', 'SHN'],['Saint Lucia', 'LCA'],['Somalia', 'SOM'],['Solomon Islands', 'SLB'],['Turks and Caicos Islands', 'TCA'],['Thailand', 'THA'],['Korea, Republic of', 'KOR'],['Taiwan, Province of China', 'TWN'],['Tajikistan', 'TJK'],['Tanzania, United Republic of', 'TZA'],['Czechia', 'CZE'],['Chad', 'TCD'],['Central African Republic', 'CAF'],['China', 'CHN'],['Tunisia', 'TUN'],['Korea, Democratic People\'s Republic of', 'PRK'],['Chile', 'CHL'],['Tuvalu', 'TUV'],['Denmark', 'DNK'],['Germany', 'DEU'],['Togo', 'TGO'],['Tokelau', 'TKL'],['Dominican Republic', 'DOM'],['Dominica', 'DMA'],['Trinidad and Tobago', 'TTO'],['Turkmenistan', 'TKM'],['Turkey', 'TUR'],['Tonga', 'TON'],['Nigeria', 'NGA'],['Nauru', 'NRU'],['Namibia', 'NAM'],['Antarctica', 'ATA'],['Niue', 'NIU'],['Nicaragua', 'NIC'],['Niger', 'NER'],['Japan', 'JPN'],['Western Sahara', 'ESH'],['New Caledonia', 'NCL'],['New Zealand', 'NZL'],['Nepal', 'NPL'],['Norfolk Island', 'NFK'],['Norway', 'NOR'],['Heard Island and McDonald Islands', 'HMD'],['Bahrain', 'BHR'],['Haiti', 'HTI'],['Pakistan', 'PAK'],['Holy See', 'VAT'],['Panama', 'PAN'],['Vanuatu', 'VUT'],['Bahamas', 'BHS'],['Papua New Guinea', 'PNG'],['Bermuda', 'BMU'],['Palau', 'PLW'],['Paraguay', 'PRY'],['Barbados', 'BRB'],['Palestine, State of', 'PSE'],['Hungary', 'HUN'],['Bangladesh', 'BGD'],['Timor-Leste', 'TLS'],['Pitcairn', 'PCN'],['Fiji', 'FJI'],['Philippines', 'PHL'],['Finland', 'FIN'],['Bhutan', 'BTN'],['Bouvet Island', 'BVT'],['Puerto Rico', 'PRI'],['Faroe Islands', 'FRO'],['Falkland Islands (Malvinas)', 'FLK'],['Brazil', 'BRA'],['France', 'FRA'],['French Guiana', 'GUF'],['French Polynesia', 'PYF'],['French Southern Territories', 'ATF'],['Bulgaria', 'BGR'],['Burkina Faso', 'BFA'],['Brunei Darussalam', 'BRN'],['Burundi', 'BDI'],['Viet Nam', 'VNM'],['Benin', 'BEN'],['Venezuela (Bolivarian Republic of)', 'VEN'],['Belarus', 'BLR'],['Belize', 'BLZ'],['Peru', 'PER'],['Belgium', 'BEL'],['Poland', 'POL'],['Bosnia and Herzegovina', 'BIH'],['Botswana', 'BWA'],['Bonaire, Sint Eustatius and Saba', 'BES'],['Bolivia (Plurinational State of)', 'BOL'],['Portugal', 'PRT'],['Hong Kong', 'HKG'],['Honduras', 'HND'],['Marshall Islands', 'MHL'],['Macau', 'MAC'],['Madagascar', 'MDG'],['Mayotte', 'MYT'],['Malawi', 'MWI'],['Mali', 'MLI'],['Malta', 'MLT'],['Martinique', 'MTQ'],['Malaysia', 'MYS'],['Isle of Man', 'IMN'],['Micronesia (Federated States of)', 'FSM'],['South Africa', 'ZAF'],['South Sudan', 'SSD'],['Myanmar', 'MMR'],['Mexico', 'MEX'],['Mauritius', 'MUS'],['Mauritania', 'MRT'],['Mozambique', 'MOZ'],['Monaco', 'MCO'],['Maldives', 'MDV'],['Moldova, Republic of', 'MDA'],['Morocco', 'MAR'],['Mongolia', 'MNG'],['Montenegro', 'MNE'],['Montserrat', 'MSR'],['Jordan', 'JOR'],['Lao People\'s Democratic Republic', 'LAO'],['Latvia', 'LVA'],['Lithuania', 'LTU'],['Libya', 'LBY'],['Liechtenstein', 'LIE'],['Liberia', 'LBR'],['Romania', 'ROU'],['Luxembourg', 'LUX'],['Rwanda', 'RWA'],['Lesotho', 'LSO'],['Lebanon', 'LBN'],['Réunion', 'REU'],['Russian Federation', 'RUS'],];

    //テーブル設定
    $(function() {
        $('#table_id').DataTable({
            data: data,
            language: {
                paginate: {
                    'previous': '≪',
                    'next': '≫'
                }
            },
            pagingType: 'custom',
        });
    });

    //PaginationType: custom の処理
    $.fn.DataTable.ext.pager.custom = function (page, pages) {
        var numbers = [];

        if (pages <= 3) {
            //全ページ数がボタン数に収まる場合
            for (var i = 0; i < pages; i++) {
                numbers.push(i);
            }
            numbers.DT_el = 'span';
            return [numbers];

        } else if (page === 0) {
            //最初のページの場合
            numbers.push(0);
            numbers.push(1);
            numbers.push(2);
            numbers.DT_el = 'span';
            return [numbers, 'next'];

        } else if (page === pages - 1) {
            //最後のページの場合
            numbers.push(page - 2);
            numbers.push(page - 1);
            numbers.push(page);
            numbers.DT_el = 'span';
            return ['previous', numbers];

        } else {
            //途中のページの場合
            numbers.push(page - 1);
            numbers.push(page);
            numbers.push(page + 1);
            numbers.DT_el = 'span';
            return ['previous', numbers, 'next'];
        }
    };
</script>
</body>
</html>

新しい pagetype である custom は、35行目からはじまる関数で定義しました。引数は2つあり、第1引数 page は「表示するページ」、第2引数 pages は「全ページ数」です。「表示するページ」は0から始まるので注意してください。
また戻り値は、パーツを配列で返します。配列の中では、決められた文字列のみをセットしてください。
前のページに移動するボタンを「≪」としたい場合でも、ここで返す値は「previous」とします。

そして30行目のように DataTablesの設定で pagetype: custom,
と指定しているだけです。
また、 previous, next も26, 27行目のように DataTables の設定で変更しています。

上記を実行すると次のように表示されます。

表の最下部にカスタマイズしたページネーションが表示されていることが判りますね。

まとめ

今回は DataTables ページネーションのカスタマイズについて紹介しました。
上記のように、簡単にカスタマイズできることを理解して頂けたものと思います。
同様な方法でお好みのページネーションを作ってください。