DESIGN / CODE / INFRA / AI

解説

複数選んだのに一つしか取れない?selectのmultipleとFormData.getAllを試そう

HTMLの複数選択は同じ名前の値を複数持つ。value・get・getAllの違いと、何も選ばないときの結果を、送信しないフォームで確認しよう。

複数選んだのに一つしか取れない?selectのmultipleとFormData.getAllを試そう
保存リストを見る →
この記事の道しるべ 6項目

HTMLとCSSの両方を選んだのに、JavaScriptで読むとHTMLしか出てこない。複数選択できることと、複数の値をまとめて受け取ることは別なんだ。

このページでは、HTMLのselectで二つの項目を選び、FormData.getAll()で全部の値を取り出せるようになることを目指す。必要なのはブラウザだけ。実際には送信せず、学びたい技術を選ぶ架空のフォームで練習するよ。

multipleで複数選択にする

selectは用意した選択肢から選ぶ入力欄。optionが一つ一つの選択肢で、multiple属性を付けると複数の項目を選べる。

<form id="sample">
  <label for="topics">学びたいもの</label>
  <select id="topics" name="topic" multiple size="3">
    <option value="html" selected>HTML</option>
    <option value="css">CSS</option>
    <option value="javascript">JavaScript</option>
  </select>
</form>

nameのtopicはフォームで使う項目名、各optionのvalueは選ばれたときの値。見える「HTML」というラベルと、渡す文字列のhtmlを区別しておこう。

sizeは表示する行数の指定で、選べる最大件数ではない。size=3なら「最大三つまで」という入力検証になるわけではないよ。

valueは全部の値を返さない

const select = document.querySelector('#topics');
console.log(select.value);

複数選択のselectでも、valueは選択された最初のoptionの値を文字列で返す。HTMLとCSSを選んだ今回の並びではhtmlが返り、二つの値の配列にはならない。

画面で複数選べているのに一つしか見えないときは、まずどの取得方法を使っているかを見よう。選択そのものが消えたとは限らないんだ。

フォームデータでは同じ名前の組が並ぶ

FormDataは、フォームの項目名と値を扱うためのWeb API。今回ならtopicという同じ名前で、選んだoptionの値がそれぞれ入る。

const form = document.querySelector('#sample');
const data = new FormData(form);

console.log(data.get('topic'));    // 'html'
console.log(data.getAll('topic')); // ['html', 'css']
console.log([...data.entries()]);
// [['topic', 'html'], ['topic', 'css']]

getは一致する名前の最初の値、getAllは一致する名前の値を配列で返す。配列は複数の値を順に持つ入れ物だよ。今回の例では、optionが文書内で並んでいる順に値が入る。利用者がクリックした順番を記録する機能ではない。

同じ名前が複数あるので、普通のオブジェクトへ一つの値としてまとめる変換をすると、値を落とすことがある。サーバーへ渡す場合も、受け取る側で複数値をどう読むか決める必要があるよ。

ページ内で二つ、次にゼロを選んでみる

  1. 最初はHTMLだけ選ばれている。getAllの表示が["html"]であることを見る。
  2. 「HTMLとCSSを選択」を押す。valueとgetはhtml、getAllは二つになる。
  3. 「送信データを確認」を押す。同じtopicが二組あることを確認する。
  4. 「選択をすべて外す」を押す。getAllは空の配列、getはnullになる。
  5. 「最初から試す」でHTMLだけが選ばれた状態へ戻す。

作例には選択を補助するボタンを用意した。パソコンではCtrlやCommandなどを使うことがあり、スマホでは選択用の画面が開くなど、直接の複数選択操作はブラウザ・OSで異なる。操作が難しい場合も、補助ボタンでデータの違いを確かめられるよ。

何も選ばない場合は、項目が入らない

このフォームではrequiredを付けていないので、すべて外した状態でもデータを確認できる。その場合、topicの組はなくなる。

確認方法 何も選ばないとき
select.value 空の文字列
data.get('topic') null
data.getAll('topic') 空の配列

topic=falseという値が自動で入るわけではないよ。少なくとも一つ選ぶことを必須にしたいなら、HTMLのrequiredや、受け付ける側での検証を設計する。画面の操作だけを頼りに、受信データは必ず正しいと考えないでね。

期待した値が取れないとき

nameが付いているか、optionのvalueが意図した文字列か、getで最初の一つだけを取っていないかを順に確認しよう。入力欄をdisabledにするとフォームデータの対象外になることも、別に確認したい条件だよ。

作例は現在の選択からその都度new FormData(form)を作る。最初に一度作ったデータを読み続けると、その後の画面の変更が自動で全部反映されるわけではないので、データを作った時点も見よう。

項目名の基本はnameとidの違い、未選択の扱いはcheckboxの送信値でも比べられる。

2026年11月1日にMDNを確認し、二つの選択、選択なし、直接の選択変更、getとgetAll、フォーム送信の抑止とリセットをChromiumの幅240・319・1280pxで検証した。

動かしてみよう:select multiple / getAll

設定や入力を切り替え、表示と結果を比べよう。最初から試すボタンで戻せるよ。

参考・出典

公開と変更の記録
  • :初回公開

日時は日本時間です。記載のある変更は、確認できた編集記録に基づきます。更新日の違いだけから変更内容を推測して載せることはありません。

更新・訂正の方針 →

みんなのコメント 0

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。