# Formの各入力要素からJSでデータを取得したうえで、AJAXを使って送信

## AJAX版の実装

JSを使った実装はこのようになります。

{% embed url="<https://codepen.io/subuta-1471420899/pen/xxwjWEb>" %}

前回と違って、画面遷移はせずに同一画面の中に結果が出力されています。対応するHTMLはこちらです。

```markup
<form id="form">
  <div class="form-example">
    <label for="name">Enter your name: </label>
    <input type="text" name="name" id="name" required>
  </div>

  <br />

  <button>Submit</button>
</form>

<div id="result"></div>
```

HTMLの中で、前回のものから変わったのは以下の部分です。

* formからaction属性を削除(利用しないので)
* form要素の後に `id="result"` な要素を追加(デバッグ出力用)

今回はJavaScriptのAJAXの機能を使ってデータ送信を行っています。JSの方も見てみましょう。

```javascript
// 各要素への参照を取得。
const $form = $("#form");
const $name = $("#name");

// form要素の送信(submit)イベントにイベントリスナー(ハンドラー)を登録
$form.on("submit", (event) => {
  // 1. デフォルトのフォーム送信の動きを止める(prevent)
  event.preventDefault();

  // 2. input要素(name="name"の要素)の現在の値(= 入力値)を取得。
  const name = $name.val();

  // 3. AJAXを使ってデータ送信する。
  $.ajax({
    // 送信先のURL(HTMLのform要素のactionに相当する部分)
    url: "https://httpbin.org/anything",
    // 送信するデータ。デフォルトでは "GET" リクエストなので、クエリ文字列(パラメータ)として付与される。
    data: { name: name }
  }).then((response) => {
    // id="result"な要素のテキストを取得したAPIのレスポンスで置き換える。
    $("#result").text(JSON.stringify(response));
  });
});

```

今回も **jQuery** を使ってデータ送信の制御を行っています。処理の流れはこういった形になっています。

1. form要素のsubmitイベントにハンドラー(Handler = イベントを扱う関数)を登録
2. submitイベントが発生したら、formのデフォルトの動き(submit)を止める。
3. 入力欄の現在の値を取得する。
4. 取得した値を所定のURLに送信する。
5. 送信結果(= レスポンス)を画面に出力(= result要素の値として表示)する。

HTML版と比べるとJSを書いている分**コード量が増えるというデメリット**はありますが、こういった**メリット**も考えられます。

* データの送信時に値を編集しやすい。(例: nameの値に別の文字列を付与・削除・置換する)
* データの送信前に独自のバリデーション(不正な値の検知)を仕込むことができる。

前回のHTMLのみでの送信を行う場合はSSRと組み合わせることが多く、今回のAJAXでの送信を行う場合はAPIを用意して行う事が多いです。サーバ側の実装に合わせて向いているものを利用できると良いかと思います。

基本的なシナリオではここまでの(HTML版, AJAX版)の実装方式で対応できますが、**フォームの入力欄が多い**場合や、**高度な機能(例: 独自のバリデーション = 不正な値の検知処理)を実装したい**場合などに、複雑なコードになりがちです。続いての章でその問題を解決する手法の一つである**データバインディング**について紹介していきます。
