質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2680閲覧

JavaScript FormDataでチェックボックスの値をまとめて取得したい

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/09/29 11:06

編集2020/09/29 14:05

前提

FormDataを使ってフォームの値を取得し、確認画面に表示することはできました。

質問

チェックボックスの箇所がチェックした数だけ表示されているので、
「Q3: B, C」のように1行で表示したい。

追記

ソースコードの問題点は["Q3",["B","C"]]とできていないことです。
そもそも、サブミットしてもQ3しか有効にならず、nameの付け方等の構成の見直しが必要です。

現在の確認画面
Q1: hoge
Q2: A
Q3: B
Q3: C

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8</head> 9 10<body> 11 <h3>Document</h3> 12 <div id="work"> 13 <p>入力画面</p> 14 <form id="form" name="myForm"> 15 <p class="text">Q1.TEXT: <input type="text" name="Q1" value="hoge" /></p> 16 <p class="radio">Q2.RADIO: 17 <input type="radio" name="Q2" value="A" checked />A 18 <input type="radio" name="Q2" value="B" />B</p> 19 <p class="radio">Q3.CHECKBOX: 20 <input type="checkbox" name="Q3" value="A" />A 21 <input type="checkbox" name="Q3" value="B" checked />B 22 <input type="checkbox" name="Q3" value="C" checked />C</p> 23 <input id="button" type="button" value="確認" /> 24 </form> 25 </div> 26 27 <script> 28 // 確認ボタンが押されたら確認画面の表示 29 document.getElementById("button").addEventListener("click", function () { 30 const workArea = document.getElementById("work"); 31 const myForm = document.getElementById('form'); 32 const formData = new FormData(myForm); 33 34 let formArray = []; 35 for (let item of formData) { 36 formArray.push(`<p>${item[0]}: ${item[1]}</p>`); 37 } 38 const html = formArray.join(""); 39 40 workArea.innerHTML = ` 41 <p>確認画面</p> 42 ${html} 43 `; 44 }); 45 </script> 46</body> 47 48</html>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/09/29 11:12 編集

現在のコードにおける問題点は何でしょうか。
kuma_kuma_

2020/09/29 11:23

> formArray.push(`<p>${item[0]}: ${item[1]}</p>`); 一度formDataのnameをキーとした連想配列に値を設定してから その値を元にpushされてはどうですか?
退会済みユーザー

退会済みユーザー

2020/09/29 13:47

m.ts10806さん ソースコードの問題点は["Q3",["B","C"]]とできていないことです。
退会済みユーザー

退会済みユーザー

2020/09/29 13:50

kuma_kuma_さん nameをキーとした連想配列に値を設定することを検討してみます。
m.ts10806

2020/09/29 13:50

質問本文に追記してください。
m.ts10806

2020/09/29 13:51

あとJavaScriptのオブジェクト的にはNGのように思います。 構成見直されたほうがよさそうに思います。
guest

回答2

0

ベストアンサー

そもそも、サブミットしてもQ3しか有効にならず、nameの付け方等の構成の見直しが必要です

サーバ側のHTTP-Body のパーサ実装 に応じて決定してください。
KoaJS (使用した middleware koa-body)では受信できました。

現在のブラウザに実装される FormData は input[type=file] の有無(または formData.append()でファイル追加したかどうか)でエンコードタイプが自動選択されます。
(かつては、常にmultipart/form-dataで送信するブラウザもありました)

  1. input[type=file] なし

enctype = application/x-www-form-urlencoded : 全ての文字をURLエンコードする。
2. input[type=file] あり
enctype = multipart/form-data : 各パートはネストしない。

※ご質問のフォーム内容を送信すると enctype は application/x-www-form-urlencoded になりますので Q1=hoge&Q2=A&Q3=B&Q3=C のデータが送信されます。

追記)
ブラウザ側の実装はPCブラウザの例となります。
スマホ用ブラウザも含めて詳細に実装をチェックするのが良いと思います。

ソースコードの問題点は["Q3",["B","C"]]とできていないことです。

回答は、愚直なコードになりますが、以下のようなコードで key が重複する場合に Array に変更する必要があります。

javascript

1 // Object.entries(formData).reduce()で簡素化できるが... 2 let keyVal = {}; 3 for (let [key, val] of formData) { 4 if ( !keyVal.hasOwnProperty(key) ) { 5 keyVal[key] = val; 6 } 7 else { 8 if ( Array.isArray(keyVal[key]) ) { 9 keyVal[key].push( val ); 10 } 11 else { 12 keyVal[key] = [keyVal[key], val]; 13 } 14 } 15 } 16 17 // 配列 or 文字列になるので、 JSON.stringify(val) を検討する 18 let html = Object.entries(keyVal) 19 .reduce( (rslt, [key,val]) => 20 rslt+`<p>${key}: ${JSON.stringify(val)}</p>`, "");

投稿2020/09/30 02:09

編集2020/09/30 02:14
AkitoshiManabe

総合スコア5432

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/30 09:36

丁寧なご回答ありがとうございました。 エンコードタイプの勉強もしていきたいと思います。
guest

0

結局サブミットすると一番最後の有効なQ3しかとれないんですけどね・・・
nameの付け方に工夫するなどが必要です

投稿2020/09/29 11:49

yambejp

総合スコア114848

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2020/09/29 11:50

一旦名寄せ処理をすればできないことはありません for (let item of Object.entries([...formData].reduce((x,y)=>(x[y[0]]=(x[y[0]]==undefined?"":x[y[0]]+",")+y[1],x),{}))) { formArray.push(`<p>${item[0]}: ${item[1]}</p>`); }
退会済みユーザー

退会済みユーザー

2020/09/29 13:53

サブミットすると一番最後の有効なQ3しかとれないのであれば、nameの付け方を考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問