input type="file" でファイル選択時にフォームの見た目を変えたい

Aug 10th, 2023 javascript css

状況

問題点

解決策

フォームの見た目を構成する要素を input 要素を分離しておく.画面に表示される label 要素を JavaScript でまとめて書き換えれば良い.

input 要素は非表示となっているため,form 要素内の何処かにあれば問題ない.

実装例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #file {
      display: none;
    }

    #form_labels {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100vh;
    }

    #form_labels label {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 300px;
      height: 100px;
      border: 1px solid black;
      cursor: pointer;
    }

    #form_labels label p {
      font-size: 20px;
    }

    #new_label {
      border: 1px solid black;
      background-color: #ccc;
    }
  </style>
</head>

<body>
  <form action="">
    <input type="file" name="file" id="file">
    <div id="form_labels">
      <label for="file">
        <p>upload</p>
      </label>
    </div>
  </form>

  <script>
    // 要素の取得
    const file = document.querySelector('#file');
    const form_labels = document.querySelector('#form_labels');

    // 変更後の label 要素(適当)
    const newLabel = [
      `<label for="file" id="new_label">`,
      `<p>file added.</p>`,
      `<p>upload more</p>`,
      `</label>`,
    ].join('');

    // ファイル選択時にラベル部分のみを変更
    file.addEventListener('change', () => {
      form_labels.innerHTML = newLabel;
    })
  </script>
</body>

</html>

所感

以上だ( `・ω・)b