submit処理応用の備忘録

久しぶりに触るJS・・・submit処理でハマったのでメモ。
使用言語はHTMLとJavaScriptです。

# やりたかったこと
以下の２つ。
1. iframeで埋め込まれた外部サイト（以下、子要素）内の情報を、子要素内の選択ボタンを押したタイミングでpost送信
2. 項目毎に選択ボタンがついた一覧情報を表示し、特定の選択ボタンを押したタイミングでその項目の情報をpost送信

# こうした
1. 子要素から一度親要素(iframeの外）に取得値を生成し、即post送信実行
2. 一覧の項目ごとにsubmitボタンと`<form>`を用意

###１の詳細
まずは内容を整理。やりたいことと、今回の条件は以下の通り。

- 情報を選択し、選択ボタンを押したタイミングでpost送信する
- 送信したい値は、iframeで埋め込んだ外部サイト内の情報
- 外部サイトでは、postMessageでリストの値を送信してくれる仕様になっている
    - postMessageを受信し、値を取得する
    - 取得値は複数、それらを全て個別にpost送信したい

これを1つずつ実装して解決していく。

######JavaScript
まず、選択した子要素の情報を親要素に持ってこないとpost送信できないので、その処理を実装する。
今回使用した外部サイトは、選択ボタンを押したタイミングでpostMessageで値（リスト）を返す形になっていたので、受信するfunctionを作成。

```Javascript
window.addEventListener("reciveMessage", receiveMessage, false);

function reciveMessage(event) {
 if (event.origin !== "http://example.org:8080") //←親要素とオリジンが一致しているか確認

}
```

これで値は取得できた。あとはどうやってpostするか。submitのやり方をおさらい。。
一度親要素にhiddenで表示して、即submit実行する事にしました（他に思いつかず）。

```Javascript
window.addEventListener("reciveMessage", receiveMessage, false);

function reciveMessage(event) {
 if (event.origin !== "http://example.org:8080") {
  var data = event.data;

  // targetに <input type="hidden" name="info" value="[取得した値]">を値の数分追加する
  for (key in data) {
   var target = document.getElementById("setInfo");
   var h_info = document.createElement("input");
   h_info.type = "hidden";
   h_info.name = "name";
   h_info.value = key.name;

   target.appendChild(h_info);

   // submit関数を実行
   document.target.submit();
  };
 };

};
```

######HTML
```html

<form action="/sum-foods" method="post">
　　　　　<div id="setInfo">
　　　　　　　　　　<iframe src="http://example.org:8080/hogehoge/child"></iframe>
　　　　　</div>
</form>
```
例えば子要素から'category', 'name', 'taste'の情報を取得した場合、
submitが実行されると以下のようになる。

```html
<form action="/sum-foods" method="post">
　　　　　<div id="setInfo">
　　　　　　　　　　<input type="hidden" name="category" value="fruit">
　　　　　　　　　　<input type="hidden" name="name" value="watermelon">
　　　　　　　　　　<input type="hidden" name="taste" value="sweet!">
　　　　　　　　　　<iframe src="http://example.org:8080/hogehoge/child"></iframe>
　　　　　</div>
</form>
```

######HTTP
リクエストボディにはこんな感じで入る。

```
scategory=fruit&name=watermelon&taste=sweet!
```


###2の詳細
やりたいことと、今回の条件は以下の通り。

- データを表示用に加工する（今回の記事では割愛）
- データの数だけ一覧に表示する
- 項目にはsubmitボタンをつける
- 選択ボタンが押されたら、その項目の情報をpost送信

######JavaScript
データの数だけ、ループでリストのエレメントを生成する。
リスト中ではsubmitボタンと送信したい情報をformで囲うようにしました。
（ソースの記載は一旦省略します。。）

######HTML
```html
　<div id="setList">
　</div>
```

画面表示時は以下のようになる。
画面表示用とsubmit用で同じ値を2回書いています。
（なんかかっこ悪いけど他に思いつかず。）

```html
<div id="setList">
　　　　　<ul>
　　　　　　　　　　<li>
　　　　　　　　　　　　　　　<div>
　　　　　　　　　　　　　　　　　　　<p>watermelon</p>
　　　　　　　　　　　　　　　　　　　<p>sweet!</p>
　　　　　　　　　　　　　　　</div>
　　　　　　　　　　　　　　　<form action="/sum-foods" method="post">
　　　　　　　　　　　　　　　　　　　　<input type="submit" value="選択">
　　　　　　　　　　　　　　　　　　　　<input type="hidden" name="name" value="watermelon">
　　　　　　　　　　　　　　　　　　　　<input type="hidden" name="taste" value="sweet!">
  　　　　　　　　　　　</form>
　　　　　　　　　　</li>
　　　　　　　　　　<li>
　　　　　　　　　　　　　　　<div>
　　　　　　　　　　　　　　　　　　　<p>bitter melon</p>
　　　　　　　　　　　　　　　　　　　<p>bitter!</p>
　　　　　　　　　　　　　　　</div>
　　　　　　　　　　　　　　　<form action="/sum-foods" method="post">
　　　　　　　　　　　　　　　　　　　　<input type="submit" value="選択">
　　　　　　　　　　　　　　　　　　　　<input type="hidden" name="name" value="bitter melon">
　　　　　　　　　　　　　　　　　　　　<input type="hidden" name="taste" value="bitter!">
  　　　　　　　　　　　</form>
　　　　　　　　　　</li>
　　　　　　　　　　<li>
　　　　　　　　　　　　　　　<div>
　　　　　　　　　　　　　　　　　　　<p>cucumber</p>
　　　　　　　　　　　　　　　　　　　<p>tasteless...</p>
　　　　　　　　　　　　　　　</div>
　　　　　　　　　　　　　　　<form action="/sum-foods" method="post">
　　　　　　　　　　　　　　　　　　　　<input type="submit" value="選択">
　　　　　　　　　　　　　　　　　　　　<input type="hidden" name="name" value="cucumber">
　　　　　　　　　　　　　　　　　　　　<input type="hidden" name="taste" value="tasteless...">
  　　　　　　　　　　　</form>
　　　　　　　　　　</li>
　　　　　</ul>
</div>
```

# おわりに
基本のsubmitだけ調べてもやりたいことが実現するのは難しいけど
やっぱり基本は理解していないと何もできないと思いました。。
あと混乱してきたら、書き出す！分解！情報揃えて眺める！ですね。

DOM操作はjQueryを使えばもっと簡単なんですよね。。勉強不足デス。。