【Bootstrap】パスワードを表示・非表示できるinputを作る

## TL;DR
- relativeとabsoluteを使う
- jsのクリックイベントでiconのclassとinputのtypeを変更する

## はじめに
目のアイコンをクリックすると「表示・非表示」できるinputを作ります。
今回は楽に実装するためにBootstrapとjQueryを使っていますが、ピュアなcssとjsでも考えは同じです。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1697698/211fae45-c28e-2928-f7da-738745ac896a.gif)

## やってみよう

他のフレームワークを用いる際は補完してください

### 全体概要
```html: index.html
<!DOCTYPE html>
<html>
  <head>
    <title>inputサンプル</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
      crossorigin="anonymous"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.0/font/bootstrap-icons.css"
    />
    <script
      src="https://code.jquery.com/jquery-3.7.0.min.js"
      integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g="
      crossorigin="anonymous"
    ></script>
  </head>
  <body>
    <div class="container">
      <form>
        <div class="my-3">
          <label for="inputPassword" class="form-label">Password</label>
          <div class="position-relative">
            <input
              type="password"
              class="form-control"
              id="inputPassword"
              placeholder="パスワードを入力してください"
            />
            <i
              id="eyeIcon"
              class="bi bi-eye translate-middle position-absolute top-50 end-0"
            ></i>
          </div>
        </div>
      </form>
    </div>
    <script>
      // eyeIconのclickクリックイベント
      $("#eyeIcon").on("click", () => {
        // eyeIconのclass切り替え
        $("#eyeIcon").toggleClass("bi-eye-slash bi-eye");

        // inputのtype切り替え
        if ($("#inputPassword").attr("type") == "password") {
          $("#inputPassword").attr("type", "text");
        } else {
          $("#inputPassword").attr("type", "password");
        }
      });
    </script>
  </body>
</html>
```

### head

cdn以下を使えるようにします
- Bootstrap
- Bootstrap-icon
- jQuery


```html: index.html
<head>
    <title>inputサンプル</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
      crossorigin="anonymous"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.0/font/bootstrap-icons.css"
    />
    <script
      src="https://code.jquery.com/jquery-3.7.0.min.js"
      integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g="
      crossorigin="anonymous"
    ></script>
</head>
```

### body

`<i>...</i>`のclassを指定すると特定のアイコンになります。
classを変えるだけというのがポイントです。

`<input>...</input>`の親divをrelative、`<i>...</i>`をabsoluteにすることでアイコンをinput基準で配置することが可能になります

`translate-middle top-50 end-0`を指定することで絶対的に上から50%、右から0%の位置に配置できます。

```html: index.html
<body>
    <div class="container">
      <form>
        <div class="my-3">
          <label for="inputPassword" class="form-label">Password</label>
          <div class="position-relative">
            <input
              type="password"
              class="form-control"
              id="inputPassword"
              placeholder="パスワードを入力してください"
            />
            <i
              id="eyeIcon"
              class="bi bi-eye position-absolute translate-middle top-50 end-0"
            ></i>
          </div>
        </div>
      </form>
    </div>
    <script>
      // eyeIconのclickクリックイベント
      $("#eyeIcon").on("click", () => {
        // eyeIconのclass切り替え
        $("#eyeIcon").toggleClass("bi-eye-slash bi-eye");

        // inputのtype切り替え
        if ($("#inputPassword").attr("type") == "password") {
          $("#inputPassword").attr("type", "text");
        } else {
          $("#inputPassword").attr("type", "password");
        }
      });
    </script>
  </body>
```

`toggleClass`を使うことで、そのクラスがある場合は削除、ない場合は付与させることができます。


## 最後に
n番煎じですが、参考になると光栄です。
初めてjQuery使いましたが、バニラjsより楽ですね