【C#入門】初学者がASP.NETでWebアプリを作る：第9回

#今回やること
Figmaでデザインを作…ろうと思ったけど記事にならないので、
一覧画面をカスタマイズして、
・日付フィルタの導入
・項目の表示/非表示の切り替え
を実装します。
※BIが使えないけどどうしてもグラフで見える化したく、Google Chart APIを使おうとしているため、
　画面にグラフの元データを持たせたい。

#日付フィルタ
日付のフィルタは範囲指定ができるようにします。
単純にカレンダーで選択する形式にして、FROM-TOの大小関係だけチェックします。
MS公式を参考に実装してみます。
[チュートリアル: 並べ替え、フィルター処理、ページングを追加する - ASP.NET MVC と EF Core](https://docs.microsoft.com/ja-jp/aspnet/core/data/ef-mvc/sort-filter-page?view=aspnetcore-5.0)

##Indexの修正
Indexメソッドに引数2つとクエリロジックを追加します。
引数2つはnullを許容しておきます。（nullの場合は無制限にする）

```C#:SalariesController.cs
        public async Task<IActionResult> Index(DateTime? dateFrom, DateTime? dateTo)
        {
            //return View(await _context.Salary.ToListAsync());

            var salaries = from s in _context.Salary select s;
            salaries = salaries.Where(x => x.RegisterUser == (User.Identity.Name ?? "DUMMY"));

            if (!(dateFrom == null) && !(dateTo == null))
            {
                salaries = salaries.Where(x => x.PaymentDate >= dateFrom && x.PaymentDate <= dateTo);
            } else if (!(dateFrom == null))
            {
                salaries = salaries.Where(x => x.PaymentDate >= dateFrom);
            } else if (!(dateTo == null))
            {
                salaries = salaries.Where(x => x.PaymentDate <= dateTo);
            }

            return View(await salaries.ToListAsync());
        }
```

##画面の修正
次に日付入力のフォームを作ります。
下記のようなフォームを追加しました。

```html:Index.cshtml
<p>
    <a asp-action="Create">データ登録</a>
</p>

<form asp-action="Index" method="get">
    <div>
        <p><input type="date" name="DateFrom" /> から <input type="date" name="DateTo" /> で <input type="submit" value="絞り込む" class="btn btn-primary" /></p>
    </div>
</form>
```

##完成
下記のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/3bce66c1-764d-1b4c-0e2b-6a78a0271389.png)

Fromで絞り込むことは出来ましたが、日付入力フォームが「年/月/日」になっていて、どういう値で絞り込んだのかわからなくなってしまいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/61f21343-2e5d-aa47-9b50-f3b5fd46b5aa.png)

さらにToで絞り込むと、Toだけの絞り込みになったので、
Fromがリセットされてしまっているとわかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/02b53e23-61dd-d9bd-3920-c29836c921a3.png)

チュートリアルをよく見て、無視していた行がありました…。
IndexメソッドとIndex.cshtmlを修正します。
ViewDataを使って初期値を画面に設定します。

```C#:SalariesController.cs
        public async Task<IActionResult> Index(DateTime? dateFrom, DateTime? dateTo)
        {
            //return View(await _context.Salary.ToListAsync());

            // 下2行を追加
            ViewData["CurrentFilterDateFrom"] = dateFrom?.ToString("yyyy-MM-dd") ?? "";
            ViewData["CurrentFilterDateTo"] = dateTo?.ToString("yyyy-MM-dd") ?? "";

            var salaries = from s in _context.Salary select s;
            salaries = salaries.Where(x => x.RegisterUser == (User.Identity.Name ?? "DUMMY"));

            if (!(dateFrom == null) && !(dateTo == null))
            {
                salaries = salaries.Where(x => x.PaymentDate >= dateFrom && x.PaymentDate <= dateTo);
            } else if (!(dateFrom == null))
            {
                salaries = salaries.Where(x => x.PaymentDate >= dateFrom);
            } else if (!(dateTo == null))
            {
                salaries = salaries.Where(x => x.PaymentDate <= dateTo);
            }

            return View(await salaries.ToListAsync());
        }
```

```html:Index.cshtml
<p>
    <a asp-action="Create">データ登録</a>
</p>

<form asp-action="Index" method="get">
    <div>
        <p><input type="date" name="DateFrom" value="@ViewData["CurrentFilterDateFrom"]"/> から <input type="date" name="DateTo" value="@ViewData["CurrentFilterDateTo"]"/> で <input type="submit" value="絞り込む" class="btn btn-primary" /></p>
    </div>
</form>
```

Fromで絞ると下記のようにFromの入力値が保持されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/9671116a-cc39-acca-c31e-387dc83bc6c3.png)

さらにToで絞り込むこともできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/b86a4721-06fc-7644-6210-13282a8ee3d7.png)

で、こうなるとクリアボタンが欲しくなるので、それも実装します。
クリアボタンは別のフォームを作ってsubmitボタンを用意するだけです。

```html:Index.cshtml
<div class="d-flex align-items-center" style="display:inline-flex">
    <form asp-action="Index" method="get">
        <input type="date" name="DateFrom" value="@ViewData["CurrentFilterDateFrom"]" /> から <input type="date" name="DateTo" value="@ViewData["CurrentFilterDateTo"]" /> で <input type="submit" value="絞り込む" class="btn btn-primary btn-sm m-2" />
    </form>
    <form asp-action="Index" method="get"><input type="submit" value="クリア" class="btn btn-secondary btn-sm m-2" /></form>
</div>
```

絞り込んで…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/97a0e6a4-fd34-c215-a1b8-5b60edd67b82.png)

クリア。（画面だけだとわからないけど、URLでパラメータがないのがわかりますね。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/6aa1796f-efa2-d6c7-71df-21856df298c8.png)

#項目の表示/非表示
モーダルウィンドウで項目の一覧を表示し、チェックを外すと非表示にしましょう。
bootstrapとjavascriptでいけそうです。
Index.cshtmlを全体的に修正します。

まずはモーダルウィンドウを表示するボタンを用意します。
data-toggle="modal" data-target="#modal1"はモーダルに必要なパラメータです。

```html
<div class="d-flex align-items-baseline" style="display:inline-flex">
    <form asp-action="Index" method="get">
        <input type="date" name="DateFrom" value="@ViewData["CurrentFilterDateFrom"]" /> から <input type="date" name="DateTo" value="@ViewData["CurrentFilterDateTo"]" /> で <input type="submit" value="絞り込む" class="btn btn-primary btn-sm m-2" />
    </form>
    <form asp-action="Index" method="get"><input type="submit" value="クリア" class="btn btn-outline-secondary btn-sm m-2" /></form>
    <div class="text-right">
        <button type="button" class="btn btn-secondary btn-sm ml-auto" data-toggle="modal" data-target="#modal1">
            項目の表示/非表示
        </button>
    </div>
</div>
```

モーダルウィンドウの定義を作ります。
div#idの"modal1"はボタンのdata-targetです。
div#classにfadeを指定するとフェードインするようになります。
見た目がわかりやすいのでcustom-switchを使います。

```html
<div class="modal fade" id="modal1" tabindex="-1"
     role="dialog" aria-labelledby="label1" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="label1">項目の表示/非表示</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body d-flex flex-column">
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input form-control-lg" type="checkbox" id="IsPaymentAmountVisible" checked onclick="changeVisible(this,'clmPaymentAmount')">
                    <label class="custom-control-label" for="IsPaymentAmountVisible">支給額</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsTravelExpenceVisible" checked onclick="changeVisible(this,'clmTravelExpence')">
                    <label class="custom-control-label" for="IsTravelExpenceVisible">交通費</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsHealthInsurancePremiumVisible" checked onclick="changeVisible(this,'clmHealthInsurancePremium')">
                    <label class="custom-control-label" for="IsHealthInsurancePremiumVisible">健康保険料</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsWelfarePensionVisible" checked onclick="changeVisible(this,'clmWelfarePension')">
                    <label class="custom-control-label" for="IsWelfarePensionVisible">厚生年金料</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsEmploymentInsurancePremiumVisible" checked onclick="changeVisible(this,'clmEmploymentInsurancePremium')">
                    <label class="custom-control-label" for="IsEmploymentInsurancePremiumVisible">雇用保険料</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsIncomeTaxVisible" checked onclick="changeVisible(this,'clmIncomeTax')">
                    <label class="custom-control-label" for="IsIncomeTaxVisible">所得税</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsResidentTaxVisible" checked onclick="changeVisible(this,'clmResidentTax')">
                    <label class="custom-control-label" for="IsResidentTaxVisible">住民税</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsTotalPaymentAmountVisible" checked onclick="changeVisible(this,'clmTotalPaymentAmount')">
                    <label class="custom-control-label" for="IsTotalPaymentAmountVisible">総支給額</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsOvertimeAllowanceVisible" checked onclick="changeVisible(this,'clmOvertimeAllowance')">
                    <label class="custom-control-label" for="IsOvertimeAllowanceVisible">時間外手当</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsMidnightAllowanceVisible" checked onclick="changeVisible(this,'clmMidnightAllowance')">
                    <label class="custom-control-label" for="IsMidnightAllowanceVisible">深夜手当</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsHolidayAllowanceVisible" checked onclick="changeVisible(this,'clmHolidayAllowance')">
                    <label class="custom-control-label" for="IsHolidayAllowanceVisible">休日手当</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsRemarksVisible" checked onclick="changeVisible(this,'clmRemarks')">
                    <label class="custom-control-label" for="IsRemarksVisible">備考</label>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" data-dismiss="modal">閉じる</button>
            </div>
        </div>
    </div>
</div>
```

各スイッチ部分はデフォルトオンにしています（checked）
onclickで呼び出す関数(changeVisible())は後で実装しますが、テーブルの列を非表示にする関数です。

```html
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input form-control-lg" type="checkbox" id="IsPaymentAmountVisible" checked onclick="changeVisible(this,'clmPaymentAmount')">
                    <label class="custom-control-label" for="IsPaymentAmountVisible">支給額</label>
                </div>
```
テーブルの各項目にidを振っておく必要があるので振ります。
※上記のchangeVisible関数の第2引数で列を指定する。

上記を全部反映すると下記のようになります。

```html:Index.cshtml
@model IEnumerable<SalaryManagementSystem.Models.Salary>

@{
    ViewData["Title"] = "一覧";
}

<h1>一覧</h1>

<p>
    <a asp-action="Create">データ登録</a>
</p>

<div class="d-flex align-items-baseline" style="display:inline-flex">
    <form asp-action="Index" method="get">
        <input type="date" name="DateFrom" value="@ViewData["CurrentFilterDateFrom"]" /> から <input type="date" name="DateTo" value="@ViewData["CurrentFilterDateTo"]" /> で <input type="submit" value="絞り込む" class="btn btn-primary btn-sm m-2" />
    </form>
    <form asp-action="Index" method="get"><input type="submit" value="クリア" class="btn btn-outline-secondary btn-sm m-2" /></form>
    <div class="text-right">
        <button type="button" class="btn btn-secondary btn-sm ml-auto" data-toggle="modal" data-target="#modal1">
            項目の表示/非表示
        </button>
    </div>
</div>

<div class="modal fade" id="modal1" tabindex="-1"
     role="dialog" aria-labelledby="label1" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="label1">項目の表示/非表示</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body d-flex flex-column">
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input form-control-lg" type="checkbox" id="IsPaymentAmountVisible" checked onclick="changeVisible(this,'clmPaymentAmount')">
                    <label class="custom-control-label" for="IsPaymentAmountVisible">支給額</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsTravelExpenceVisible" checked onclick="changeVisible(this,'clmTravelExpence')">
                    <label class="custom-control-label" for="IsTravelExpenceVisible">交通費</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsHealthInsurancePremiumVisible" checked onclick="changeVisible(this,'clmHealthInsurancePremium')">
                    <label class="custom-control-label" for="IsHealthInsurancePremiumVisible">健康保険料</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsWelfarePensionVisible" checked onclick="changeVisible(this,'clmWelfarePension')">
                    <label class="custom-control-label" for="IsWelfarePensionVisible">厚生年金料</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsEmploymentInsurancePremiumVisible" checked onclick="changeVisible(this,'clmEmploymentInsurancePremium')">
                    <label class="custom-control-label" for="IsEmploymentInsurancePremiumVisible">雇用保険料</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsIncomeTaxVisible" checked onclick="changeVisible(this,'clmIncomeTax')">
                    <label class="custom-control-label" for="IsIncomeTaxVisible">所得税</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsResidentTaxVisible" checked onclick="changeVisible(this,'clmResidentTax')">
                    <label class="custom-control-label" for="IsResidentTaxVisible">住民税</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsTotalPaymentAmountVisible" checked onclick="changeVisible(this,'clmTotalPaymentAmount')">
                    <label class="custom-control-label" for="IsTotalPaymentAmountVisible">総支給額</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsOvertimeAllowanceVisible" checked onclick="changeVisible(this,'clmOvertimeAllowance')">
                    <label class="custom-control-label" for="IsOvertimeAllowanceVisible">時間外手当</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsMidnightAllowanceVisible" checked onclick="changeVisible(this,'clmMidnightAllowance')">
                    <label class="custom-control-label" for="IsMidnightAllowanceVisible">深夜手当</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsHolidayAllowanceVisible" checked onclick="changeVisible(this,'clmHolidayAllowance')">
                    <label class="custom-control-label" for="IsHolidayAllowanceVisible">休日手当</label>
                </div>
                <div class="custom-control custom-switch m-1">
                    <input class="custom-control-input" type="checkbox" id="IsRemarksVisible" checked onclick="changeVisible(this,'clmRemarks')">
                    <label class="custom-control-label" for="IsRemarksVisible">備考</label>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" data-dismiss="modal">閉じる</button>
            </div>
        </div>
    </div>
</div>

<table class="table">
    <thead>
        <tr>
            <th id="clmBeneficiary">
                @Html.DisplayNameFor(model => model.Beneficiary)
            </th>
            <th id="clmPaymentType">
                @Html.DisplayNameFor(model => model.PaymentType)
            </th>
            <th id="clmPaymentDate">
                @Html.DisplayNameFor(model => model.PaymentDate)
            </th>
            <th id="clmPaymentAmount">
                @Html.DisplayNameFor(model => model.PaymentAmount)
            </th>
            <th id="clmTravelExpence">
                @Html.DisplayNameFor(model => model.TravelExpence)
            </th>
            <th id="clmHealthInsurancePremium">
                @Html.DisplayNameFor(model => model.HealthInsurancePremium)
            </th>
            <th id="clmWelfarePension">
                @Html.DisplayNameFor(model => model.WelfarePension)
            </th>
            <th id="clmEmploymentInsurancePremium">
                @Html.DisplayNameFor(model => model.EmploymentInsurancePremium)
            </th>
            <th id="clmIncomeTax">
                @Html.DisplayNameFor(model => model.IncomeTax)
            </th>
            <th id="clmResidentTax">
                @Html.DisplayNameFor(model => model.ResidentTax)
            </th>
            <th id="clmTotalPaymentAmount">
                @Html.DisplayNameFor(model => model.TotalPaymentAmount)
            </th>
            <th id="clmOvertimeAllowance">
                @Html.DisplayNameFor(model => model.OvertimeAllowance)
            </th>
            <th id="clmMidnightAllowance">
                @Html.DisplayNameFor(model => model.MidnightAllowance)
            </th>
            <th id="clmHolidayAllowance">
                @Html.DisplayNameFor(model => model.HolidayAllowance)
            </th>
            <th id="clmRemarks">
                @Html.DisplayNameFor(model => model.Remarks)
            </th>
            @*<th>
                    @Html.DisplayNameFor(model => model.RegisterDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.RegisterUser)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.UpdateDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.UpdateUser)
                </th>*@
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Beneficiary)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.PaymentType)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.PaymentDate)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.PaymentAmount)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.TravelExpence)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.HealthInsurancePremium)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.WelfarePension)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.EmploymentInsurancePremium)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.IncomeTax)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ResidentTax)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.TotalPaymentAmount)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.OvertimeAllowance)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.MidnightAllowance)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.HolidayAllowance)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Remarks)
                </td>
                @*<td>
                        @Html.DisplayFor(modelItem => item.RegisterDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.RegisterUser)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.UpdateDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.UpdateUser)
                    </td>*@
                <td>
                    <a asp-action="Edit" asp-route-id="@item.Id">編集</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">詳細</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">削除</a>
                </td>
            </tr>
        }
    </tbody>
</table>
```

site.jsにchangeVisible関数を実装します。
site.jsはデフォルトで読み込まれる設定が入っているので、cshtml側で読み込む処理を新たに書く必要はありません。

```javascript:site.js
function changeVisible(obj, id) {
    var CELL = document.getElementById(id);
    var TABLE = CELL.parentNode.parentNode.parentNode;
    for (var i = 0; TABLE.rows[i]; i++) {
        TABLE.rows[i].cells[CELL.cellIndex].style.display = (obj.checked) ? '' : 'none';
    }
}
```

上記で実装完了です。
動かしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/1445a84b-dd20-8703-27a1-9dbb1938d4bc.png)

項目の表示/非表示ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/148ec9cb-eec4-8b5a-89d4-d238b8242fa7.png)

スイッチを押すとグレーになり、その項目が背景の一覧画面で表示されなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/7d002c3d-b0b9-ec7d-10f9-175876e378c0.png)

右上の×か閉じるボタンで閉じます。
スイッチをクリックした時点で表示を切り替えているので、モーダルを閉じるだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/bff32a0e-b060-314e-d617-6adf82588ba8.png)

ただ、これには欠点があり、日付フィルタを使用したり、詳細画面に遷移して一覧に戻ってしまうとすべての項目が表示されてしまいます。
また、利用者目線で考えると、全て表示/非表示くらいは1ボタンでやりたくなります。
前者は日付フィルタも同じなので一旦置いておき…
後者を実装します。

##全て表示/非表示ボタンの実装
HTML+javascriptだけでいきます。
まずモーダルのフッターにボタンを用意します。

```html
<div class="modal-footer">
    <button type="button" class="btn btn-primary" onclick="toAllVisible(true)">すべて表示</button>
    <button type="button" class="btn btn-outline-secondary" onclick="toAllVisible(false)">すべて非表示</button>
    <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
</div>
```

toAllVisibleを実装します。
各スイッチのvalueに基づいて、下記のように処理します。
①すべて表示したいとき(引数がtrue)は、checked==falseのスイッチをすべてクリックする
②すべて非表示したいとき(引数がfalse)は、checked==trueのスイッチをすべてクリックする
つまり、checked!=引数のスイッチをすべてクリックします。

```javascript
var switchIds = ['IsPaymentAmountVisible', 'IsTravelExpenceVisible', 'IsHealthInsurancePremiumVisible', 'IsWelfarePensionVisible',
                'IsEmploymentInsurancePremiumVisible', 'IsIncomeTaxVisible', 'IsResidentTaxVisible', 'IsTotalPaymentAmountVisible',
                'IsOvertimeAllowanceVisible', 'IsMidnightAllowanceVisible', 'IsHolidayAllowanceVisible', 'IsRemarksVisible']

function toAllVisible(visible) {
    for (var i = 0; i < switchIds.length; i++) {
        var switchObj = document.getElementById(switchIds[i]);
        if (switchObj.checked != visible) {
            switchObj.click();
        }
    }
}
```

出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/8250f46d-9ee5-b5a2-5e51-bafdf15bafbc.png)

##日付フィルタの修正
詳細画面や編集画面に遷移した後、一覧画面に戻るとフィルタが解除されてしまうので、それを解消します。
フィルタ情報をTempDataで持つようにして、詳細画面 or 編集画面のどちらかからの遷移の場合、
TempDataから取り出したフィルタ条件で絞り込みます。
もっといい方法がある気がしますがごり押しです…

```C#:SalariesController.cs
        // GET: Salaries
        public async Task<IActionResult> Index(DateTime? dateFrom, DateTime? dateTo)
        {
            //return View(await _context.Salary.ToListAsync());

            var refUrl = Request.Headers["Referer"].ToString();
            var refUri = new System.Uri(refUrl);
            if (refUri.Segments.Length > 2 && (refUri.Segments[2] == "Details/" || refUri.Segments[2] == "Edit/"))
            {
                dateFrom = TempData["CurrentFilterDateFrom"] as DateTime?;
                dateTo = TempData["CurrentFilterDateTo"] as DateTime?;
            }

            TempData["CurrentFilterDateFrom"] = dateFrom?.ToString("yyyy-MM-dd") ?? (TempData["CurrentFilterDateFrom"] as DateTime?)?.ToString("yyyy-MM-dd");
            TempData["CurrentFilterDateTo"] = dateTo?.ToString("yyyy-MM-dd") ?? (TempData["CurrentFilterDateTo"] as DateTime?)?.ToString("yyyy-MM-dd");
            
            TempData.Keep();

            var salaries = from s in _context.Salary select s;
            salaries = salaries.Where(x => x.RegisterUser == (User.Identity.Name ?? "DUMMY"));

            if (!(dateFrom == null) && !(dateTo == null))
            {
                salaries = salaries.Where(x => x.PaymentDate >= dateFrom && x.PaymentDate <= dateTo);
            } else if (!(dateFrom == null))
            {
                salaries = salaries.Where(x => x.PaymentDate >= dateFrom);
            } else if (!(dateTo == null))
            {
                salaries = salaries.Where(x => x.PaymentDate <= dateTo);
            }

            return View(await salaries.ToListAsync());
        }
```

Index.cshtmlのほうもTempDataに変えます。

```html:Index.cshtml
<div class="d-flex align-items-baseline" style="display:inline-flex">
    <form asp-action="Index" method="get">
        <input type="date" name="DateFrom" value="@TempData["CurrentFilterDateFrom"]" /> から <input type="date" name="DateTo" value="@TempData["CurrentFilterDateTo"]" /> で <input type="submit" value="絞り込む" class="btn btn-primary btn-sm m-2" />
    </form>
    <form asp-action="Index" method="get"><input type="submit" value="クリア" class="btn btn-outline-secondary btn-sm m-2" /></form>
    <div class="text-right">
        <button type="button" class="btn btn-secondary btn-sm m-2" data-toggle="modal" data-target="#modal1">
            項目の表示/非表示
        </button>
    </div>
</div>
```

#次回予告
何がダメってMVCしてないのがダメな気がしてきたのでMVC（というよりMVVCかな？）にしたい。