【Salesforce】【LWC】リストのページングとページ遷移ボタン

# やりたいこと
リストはulタグ＋liタグでもDataTableでもなんでもいいのですが
ページングしてこんな↓感じのボタンで遷移したいというのが要件です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/f4ad0ffb-1a06-964b-2421-cbfec9481121.png)

# Radio Groupで実装してみた
最初はカスタムでボタンを作ろうかと考えてたのですが
[Radio Group](https://developer.salesforce.com/docs/component-library/bundle/lightning-radio-group/example)でボタン形式ができるみたいなのでやってみました。

リードレコードを20件ずつ表示する画面です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/0654d0aa-0f0b-401a-672b-b40438523633.png)

リードが150件ある場合の動作が以下の感じです。
![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/c167be52-907b-78df-18bc-d03b9b6e7b00.gif)


# ソースコードとポイント解説
```html:LeadList.html
<template>
    <lightning-card>
        <div class="slds-m-around_xxx-small">
            {resultMessage}
        </div>
        <div class="slds-m-around_xxx-small">
            <lightning-datatable
                key-field="Id"
                data={displayList}
                columns={columns}
                show-row-number-column
                hide-checkbox-column>
            </lightning-datatable>
        </div>
        <div class="slds-m-top_small slds-align_absolute-center">
            <lightning-radio-group 
                name="page"
                label="page"
                variant="label-hidden"
                options={pageOptions}
                value={pageValue}
                onchange={changePage}
                type="button">
            </lightning-radio-group>
        </div>
    </lightning-card>
</template>
```
結果メッセージ、データテーブル、ラジオグループとシンプルな構成です。
ラジオグループは`type="button"`を指定します。

```javascript:LeadList.js
import { LightningElement, track} from 'lwc';
import getLeadList from '@salesforce/apex/LeadListController.getLeadList';

export default class LeadList extends LightningElement {
    // 画面読込時に取得するリードリスト
    @track leadList = [];
    // 表示用のリスト
    displayList = [];
    // 1ページあたりのレコード数
    displayRecordSize = 20;
    // 結果メッセージ
    resultMessage = '';
    // リードリストのカラムヘッダー
    columns = [
        { label: '氏名', fieldName: 'Name' },
        { label: '会社名', fieldName: 'Company' },
        { label: 'メールアドレス', fieldName: 'Email', type: 'email' },
    ];

    // 選択ページ（デフォルトは1を設定）
    pageValue = 1;
    // ページ数の取得　ラジオボタン1～を生成
    get pageOptions(){
        var pages = [];

        const pageSize = Math.floor((this.leadList.length - 1) / this.displayRecordSize) + 1;
        for(let i = 1; i <= pageSize; i++){
            pages.push({ label: i, value: i });
        }

        return pages;
    }

	connectedCallback() {
        this.init();
	}

    async init() {
        // リードを取得
        this.leadList = await getLeadList({});

        if(this.leadList.length == 0){
            this.resultMessage = '検索結果：データが見つかりませんでした';
            return;
        }

        this.resultMessage = '検索結果：'+ this.leadList.length +'件';
        // 表示用リストの更新
        this.switchDisplayList();

    }

    // ボタン押下処理
    changePage(event){
        // 選択したボタンの番号を設定
        this.pageValue = Number(event.detail.value);
        // 表示用リストの更新
        this.switchDisplayList();
    }

    // 表示用リストの更新　選択中のボタンの番号で表示するデータを切り替える
    switchDisplayList(){
        var start = (this.pageValue-1)*this.displayRecordSize;
        var end = ( (this.pageValue-1)*this.displayRecordSize+this.displayRecordSize > this.leadList.length ) ? this.leadList.length : (this.pageValue-1)*this.displayRecordSize+this.displayRecordSize;
        this.displayList = this.leadList.slice(start,end);
    }
}
```

データ格納用の`leadList`と表示用の`displayList`を分けています。
`displayRecordSize`で1ページ当たりのレコード数を定義しておくと楽です。
`get pageOptions()`では取得したデータ数を見てボタン要素を動的に追加しています。
`switchDisplayList()`の処理が一番重要です。選択されたページ番号で表示データを切り替えます。

```apex:LeadListController
public with sharing class LeadListController {

    @AuraEnabled(cacheable=true)
    public static List<Lead> getLeadList(){
        return [SELECT Name, Company, Email FROM Lead ORDER BY Name LIMIT 200];
    }
}

```
ApexはSOQLクエリしているだけです。
ここでLIMIT指定しないと画面に表示されるボタンの数がえげつないことになりますので注意です。

簡単につくってみたかったのでこんな感じになりました。
よければご参考ください(^^)/