【Laravel】画面で指定したソート条件をページング先でも反映させる

画面上でボタンなどでソート条件を指定→ページング先でも反映させるための一連の手順です。

## やりたいこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/c2182529-ceec-0ce6-4512-016f3a8a63f7.png)


## 環境

- PHP：バージョン7.3.7
- Laravel：バージョン5.8
- OS：Windows10

## 手順
### 1. ページング機能の作成
まずはページング機能を作成します。
ControllerとViewを編集するだけなので、わりと簡単。

#### (1)Controllerの編集
全件を取得し、1ページ当たり5データ表示させる場合は以下の通り。
pagenate()のカッコ内の数字を任意の数字に変えましょう。

```php:TestController.php

    public function initialize(){

        $test_forms = TestForm::all();　// テーブル：test_formsから全件を取得
        $test_forms = TestForm::paginate(5);　// 1ページに表示されるデータを5件に設定
        return view('test_list', ['test_forms' => $test_forms]);

    }
```

#### (2)Viewの編集
Viewにページングを効かせる記述を追加します。
アロー演算子（->）の左辺にはControllerで渡した変数を記述。

```php:test_list.blade.php
 {{ $test_forms->links() }}
```

### 2. ソート機能の追加
続いてソート機能。
専用のプロジェクトを追加するので、ページングよりは少し手間がかかります。

#### (1)ソート用パッケージのインストール
ソート用パッケージ、kyslik/column-sortableをインストールします。
コマンド実行場所は作成したLaravelプロジェクト直下です。

```
> composer require kyslik/column-sortable
```


#### (2)ソート用パッケージの設定ファイルの作成
続いて設定ファイルの作成。
こちらもコマンド実効場所はプロジェクト直下。

```
> php artisan vendor:publish --provider="Kyslik\ColumnSortable\ColumnSortableServiceProvider" --tag="config"
``` 


#### (3)config/app.phpへの追記
config/app.phpのproviders配列に以下の通り追記します。
これで、今回インストールしたサービスプロバイダクラスが読み込まれるようになります。

```php:config/app.php
    'providers' => [
        
        Kyslik\ColumnSortable\ColumnSortableServiceProvider::class, //追加

    ],
```

#### (4)モデルの編集
モデルクラスにソート対象を記述します。
「public $sortable =」に、ソート対象を配列形式で。
※要素は後の手順で出てくるViewの@sortablelink()の第1引数に一致させます。

```php:TestForm.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Kyslik\ColumnSortable\Sortable;　// 追加

class TestForm2 extends Model
{
    
    use Sortable; // 追加
    public $sortable = ['id', 'name', 'created_at', 'updated_at'];　// 追加

}
```


#### (5)Controllerの編集
Controllerの「paginate()」の前に「sortable()->」を追記します。

```php:TestController.php

    public function initialize(){

        $test_forms = TestForm::all();
        $test_forms = TestForm::sortable()->paginate(5); // sortable()->を追記
        return view('test_list', ['test_forms' => $test_forms]);

    }
```

#### (6)Viewの編集

##### ①ソート対象を@sortablelink()で記述
- 第1引数：ソート対象のカラム名
- 第2引数：画面に表示する文字列（省略するとカラム名が表示される）

を入力します。必要に応じて、

- 第3引数：デフォルトのクエリストリング(省略可)
- 第4引数：追加のアンカータグの属性(省略可)

も入力しましょう。

```php:test_list.blade.php
@section('content')
    <table class = "table">
        <thead>
            <tr>
                <td>@sortablelink('id', 'ID')
                <td>@sortablelink('name', '名前')
                <td>@sortablelink('created_at', '作成日')
                <td>@sortablelink('updated_at', '更新日')
        </thead>
        @foreach($test_form2s as $test_form2)
        <tbody>
            <tr>
                <td>{{ $test_form2->id }}
                <td>{{ $test_form2->name }}
                <td>{{ $test_form2->created_at }}
                <td>{{ $test_form2->updated_at }}
        </tbody>
        @endforeach
    </table>
```

##### ②ページングを効かせる記述を変更 →【ココが重要！】
ページング機能作成時にViewに記述した「 {{ $test_forms->links() }}」を以下のように修正します。
「->appends(request()->query())->」を追加してあげることで、ページングで次のページの内容を読み込んでも画面でしていたソート条件が反映されます。
※appendsのsを忘れないようにしましょう。

```php:test_list.blade.php
{{ $test_forms->appends(request()->query())->links() }}
```

## 参考
- [Laravel5.7: ページネーションの機能を追加する | Qiita](https://qiita.com/sutara79/items/e9b83b0ef9b069b519a3)
- [laravelのページネーションにソート機能を追加する | Qiita](https://qiita.com/haserror/items/e7daeae404b675f739e1)
- [DBの操作について（一覧表示＆ページネーション）| Laravel学習帳](https://laraweb.net/tutorial/2645/)
- [laravelのぺジネーション　ページ移行後の不具合 | teratail](https://teratail.com/questions/135550)