JavaScriptのライブラリJQueryでイベント発火・Ajax（非同期通信を実装する場合）

#前提

- 非同期通信
- Ruby.Rails
- 送信フォームが送信（sendボタン押す）されたらカラーのパネルが追加させる実装を行うことを例にする。
- ＜例＞発火すると右上に選択した色が非同期通信で表示される。

※非同期通信の手順をjQuery導入から全て確認したい方のまとめは[こちら](https://kayoblog.org/programming_myapp_hidoukitushin/)

![スクリーンショット 2020-10-16 15.09.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/8cdba4d0-fa69-ee23-defe-7217947b22e4.png)

　
#イベントが発火した際にあることが実行されるようにする
①何をきっかけに（＝イベントは何？）
②イベントきっかけにどんなとこを実行するか

この２つを考えながらコードを考える。

###「今回は送信ボタンを押したら（イベント）カラーパネルが追加されることが実行される」

①送信ボタンを押すということは「フォームが送信された時」だと考える。
②イベントをきっかけにカラーパネルが表示されるにはいくつかの工程が必要だと考える。
　→Ajaxを使用（データ関連の引き渡し）
　→HTMLで変化後の見た目（イベント発火をきっかけに起こる一部見た目の変化）
 

##①何をきっかけに（イベント発火は何？）
####きっかけはフォームの送信
「フォームのボタンを押した時」というのを記述。


```ruby:###.js(JavaScriptファイル)
$(function(){
  $(*****).on(*****, function(){

  })
})
```

フォームに設定したのクラス名を $(　)に入れて、
「.on」で押すという意味を加える。
「on(　, 」のon( の後には何を押すのかをいれる。
今回は'submit'ボタンを入れた。
 

```ruby:＜記述例＞
$(function(){
  $('.js-form').on('submit', function(){

  })
})
```

また、console.logを用いてイベント発火しているか確認もしてみてください。
空いている行に記述して送信ボタンを押すことで確認できます。
＜例＞console.log("テスト")
などカッコに入れてみてください。
![スクリーンショット 2020-10-16 16.15.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/fa2d0025-0464-dd9e-3a5b-b3d221d36565.png)
できていない時は検証のコンソールでエラーが出るはずです。

　　
####次に、デフォルト設定の方のフォーム送信を停止
今のままだとデフォルトの設定として、
フォーム送信と共に画面が今まで通り（非同期通信ではなく）画面遷移（画面移動）してしまう。
通常設定は阻止する必要がある。
非同期通信を行うために、preventDefault()を使用する。

```ruby:###.js(JavaScriptファイル)

  $(*****).on(*****, function(e){
    e.preventDefault()
  
  })
})
```
この際も真ん中の空いている行にconsole.logを入れてエラーが出てないか確認してみてください。
　
　
　
##②イベントきっかけにどんなとこを実行するか
- Ajaxを使用（データ関連の引き渡し）
- HTMLで変化後の見た目（イベント発火をきっかけに起こる一部見た目の変化）

###Ajaxを使用（データ関連の引き渡し）

この後必要になる基本のコード
先ほどのコードに 「$.ajax({」から追加しています。

```javascript:javascripts/###.js
$(function(){
  $(*****).on(*****, function(e){
    e.preventDefault()
    // ここから下追加記述
    $.ajax({
      url: 取得したリクエストURL,  //同期通信でいう『パス』
      type: 'POST',  //同期通信でいう『HTTPメソッド』
      data: 取得したFormData,  
      dataType: 'json',
      processData: false,
      contentType: false
    })
  })
})
```
↑この記述を行っても遷移先のviewファイル(〇〇.json.jbuilder)を作成していないとエラーが出ます。
　
####ここからは送信フィームをイベントとした例を元にみていきます。

```javascript:＜例＞
$(function() {
  $('.js-form').on('submit', function(e) {
    e.preventDefault();
    // ここから下追加記述
    let formData = new FormData(this);
    let url = $(this).attr('action');
    $.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
    })
  });
});
```

　
#####「フォームに入力された値を受け取れるようにする記述をする」
#####FormData
 
フォームのデータの送信に使用。
new FormData(フォーム要素)とすることでFormDataを作成。
今回の場合オブジェクトの引数はthis。
イベントで設定したfunction内でthisを利用した場合は、
イベントが発生したノード要素を指す。
今回の場合は、js-formというクラスがついたフォームの情報を取得している。
IDなどでも取得できる。

```javascript:＜例＞のFormDataについて
   let formData = new FormData(this);
```
 

　

#####attrメソッド

引数に指定した属性の値を取得することができる。

```javascript:＜例＞のattrメソッドとurlについて
let url = $(this).attr('action');
```
例では引数に'action'を指定しているので(ここではthis)from要素のaction属性の値が取得できる。
![スクリーンショット 2020-10-16 19.16.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/7ea63c78-16ca-b81a-cbb5-f9dc1c4fe125.png)

「/songs/3/songcolors」このパスがactionから取れてurlに入れられてる。
そのurlがAjaxのurlに関わってくるのだと思います。
　　
　
　

#####「$.ajax」の部分に非同期通信に必要なオプションを設定

```javascript:＜例＞$.ajaxからの記述
    $.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
    })
```

| オプション | 内容 |
|----------|------|
| type |HTTP通信の種類を記述する。通信方法は、GETとPOSTの2種類。|
|url |リクエストを送信する先のURLを記述する。遷移先、パス |
|data|サーバに送信する値を記述する。今回はデータを格納したものが入る。|
|dataType|サーバから返されるデータの型を指定する。|
|processData|デフォルトではtrue。dataに指定したオブジェクトをクエリ文字列(例: msg.txt?b1=%E3%81%8B&b2=%E3%81%8D )に変換する役割。|
|contentType|サーバにデータのファイル形式を伝えるヘッダ。FormDataをつかってフォームの情報を取得した時には必ずfalseにする。さらに詳しくは[こちら](http://js.studio-kingdom.com/jquery/ajax/ajax)。

　　
　
　

　

###HTMLで変化後の見た目（イベント発火をきっかけに起こる一部見た目の変化）
非同期通信の結果（ブラウザの見た目としての変化）として返ってくるデータは、done(function(data) { 処理 })の関数の引数で受け取る。
doneメソッドを使う。

また、doneメソッドで受け取った引数( )を元に「function buildHTML〜」の後からHTMLを組み立てる。

```javascript:javascripts/###.js
$(function(){
　 //ここから下５行追記
  function buildHTML(***jsファイル名***){
    let html = `<*******>
                </*******>`//`から`の間にHTMLが入る。
    return html;
  }
  $(*****).on(*****, function(e){
    e.preventDefault()
    let formData = new FormData(this); //フォームからデータをとってくる場合この一文を必要とする。
    let url = $(this).attr('action'); //フォームのアクションに指定されたものが必要になる場合この一文が必要。
    $.ajax({
      url: 取得したリクエストURL,  //同期通信でいう『パス』
      type: 'POST',  //同期通信でいう『HTTPメソッド』
      data: 取得したFormData,  
      dataType: 'json',
      processData: false,
      contentType: false
    })
　　 //ここから以下追記
    .done(function(data){
      let html = buildHTML(data);
      $('.***ボタンのクラス***').prop('disabled', false) //一度押すと押せなくなる送信ボタンを連続で押せるようにしている
      $('***元のHTMLに追加したい場所を指定***').prepend(html);//.prepend指定した要素の最初に、引数で指定した内容を追加
    })
  })
})
```
#####doneメソッド
.when( ) は先に実行したい処理。
.done( ) は後で実行したい処理。
のように処理をいつしたいか設定できます。
　

#####$('.ボタンのクラス').prop('disabled', false)
disabled属性をfalseにする記述でsubmitボタンが押せないのをfalseで解除する。
　
##### function buildHTMLL(　){let html = `<*******></*******>return html;}
doneメソッドで受け取った引数( )を元にHTMLを組み立てる。
HTMLの組み立てはつど全く違っているのでここに記述しておりませんが自分のコードを例に置いておいきます。

```javascript:＜例＞HTMLの箇所をピックアップしたもの
  function buildHTML(songcolor){
    let html =
      `<li class="color-box" style="background-color:${songcolor.color}"></li>`
    return html;
  };
```
検証ツールで追加したいHTMLを見てみるととてもわかりやすいのと、
データベースの情報を表示する際は${}を使用すること、
ここに持ってくる情報は対応するviweに作った.json.jbuilderに設定したことを思い出すとわかりやすいかも。

　
##### prependメソッド
元のHTMLのどの部分に追加するのかクラスなどを指定して決める。
指定した要素（クラスなど）の最初に足すことができる。
そのほかにも最後に足したりするメソッドなども存在する。
　

　

　

このように様々なメソッドを使用することで、
テキストボックス内をイベント後に空にしたり設定することができる。

　
　
　
　
　
##イベント発火により実行することが実装できたら…
###その実行ができなかった場合を想定する

```javascript:javascripts/###.js
$(function(){
  function buildHTML(******){
    let html = `<*******>
                </*******>`
    return html;
  }
  $(*****).on(*****, function(e){
    e.preventDefault()
    let formData = new FormData(this);
    let url = $(this).attr('action');
    $.ajax({
      url: 取得したリクエストURL,
      type: 'POST',
      data: FormData,  
      dataType: 'json',
      processData: false,
      contentType: false
    })
    .done(function(data){
      let html = buildHTML(data);
      $('.******').prop('disabled', false)
      $('******').prepend(html);
    })
　　 //ここから以下追記
    .fail(function(){
      alert('error');
　　 });
  })
})
```
#####failメソッド
サーバーエラーの場合にdoneではなくfailが呼び出される。
　

#####alertメソッド
アラートが呼び出される。('****')の中身の文字がアラートで表示される。
　
　
　
　
　
　
以上です！
これで非同期通信の作業は最後です。
ほかにも様々な設定ができるのでこればかりではないのですが、
一旦ここで終わります。
　
　
　
　
#最後にひとこと
ここまでまとめてみて、
一つ一つの記述の意味がより理解できました。
ただ、実際に新たに自分のオリジナルのアプリを開発したからというのも合わさって
今回の理解につながったのだと思います。

###新たな疑問点や課題
- 非同期通信をする際の手順を自分で思い出しながら実装できるかの不安
- doneメソッドの引数であるHTMLの組み立て
- done後の様々な記述
- Ajax後の設定が他で応用できるのか
- 非同期通信以外にJavaScriptでできることがあるがどんな仕組みなのか
　
　


理解が深まっていても実装で使用できるか
また、まだまだ理解が追いついていない部分を学習していきたいと思います。
　
　
初めてJSみた時はこんなの読めないと思っていましたが
今は少し見慣れてパーツごとに見れるようになったのが嬉しいです。
　
　
　
　
最後まで読んでくださってありがとうございました！
ではまた〜


#関連リンク
非同期通信の流れをjQueryの導入から全て記載しているのは[こちら](https://kayoblog.org/programming_myapp_hidoukitushin/)