【JavaScript・HTML・(Python)】tableにあるボタンを押した行をモーダル上で削除する

### ※注意！！
タイトルでは、「削除する」とありますが、記事に書いているのは、**tableの1行をボタンを押してモーダルを出す→削除する手前まで！！！** です。
削除機能実装については書いていませんのでご了承ください。


## 本記事の目的
1. JavaScriptを使って「欲しい！！」と思った**テーブルの行の情報を取得**できるようになる
1. ボタンをクリックして、**クリックした行の情報を取得**できるようになる
1. 上から降ってきた画面(モーダル)上のボタンを押して、プログラムを実行する手前まで実装することができる

の3つです！

## 目次
1. 実装した機能
1. この記事を書こうとした経緯
1. 具体的な実装方法
1. 参考にしたサイト

## 1. 実装した機能

今回実装したい機能は、こんな感じです。
![event_category_delete.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782282/6eeb43cc-f554-cd59-1f1f-d6f5f5c76e3a.gif)



## 2. この記事を書こうとした経緯

1. 上記の機能を実装したいと思った
1. だけど、テーブル上のボタンを押して、**押した行をデータベースから削除するには**どうしたらいいんだろう？？？
1. 色々Googleで調べたけど、テーブルのボタンを押してモーダル(上からニョキって出てくる画面)を出す→モーダルのボタンを押して初めて削除する、ような機能をまとめて書いてある記事はなくて困った。。。
1. 自分が書こう！

です。


## 3. 具体的な実装方法


実装のフェーズを2段階に分けました。

1. テーブル横の削除ボタンを押したらモーダルを出す
1. モーダルの削除ボタンを押したら「削除」が実行される

ここでもう少し詳細に書くと、
```
①テーブル横の削除ボタンを押した瞬間、押した行の情報(上記Gifでいうと「イベントカテゴリid」と「イベントカテゴリ名」のこと)を取得する 
※理由：DBで登録されているデータを削除するときに「イベントカテゴリid」を参照して削除するため。
②モーダルを出す
③モーダル上の削除ボタンを押したら「削除」が実行される
```
の3段階に分けることができます。

※私自身、ここをどう実装しようか苦戦したため、Webアプリ開発初心者なりに考えて書きました。他にいい方法など知っている方がいれば是非コメントを残していただけると幸いです。

実装全体の流れ(自分のアイデア)
```
■JavaScriptで、 「テーブルの情報をすべて取得」 する
■JavaScriptで、ボタンを 「押した行のインデックスを取得」 する
■JavaScriptで、取得したテーブルの全情報から、インデックスを参照して、 「押した行の情報を取得」 する
■HTMLで、モーダルを出す & モーダル上の削除ボタンを押して「削除」が実行される手前までを行う
```

<br>

■JavaScriptで、テーブルの情報を**すべて**取得する

```javascript
  //table全情報を格納する空の配列を作成
  let table_tr = new Array(0)

  window.onload = function() {

    // idからtable全情報を取得
    let table = document.getElementById('targetTable')

    // 2重のfor文で、セルの要素1つずつ取得
    for (var i=0; i<table.rows.length; i++){
      record = new Array(0)
      // length.-1している理由は、上記Gifの詳細・削除ボタンの列の情報は必要ないため。
      for (var j=0; j<table.rows[i].cells.length-1; j++){
        // 1行分の情報
        record.push(table.rows[i].cells[j].innerHTML)
      }
      // 1行目に書いた、全情報を格納する空の配列に追加
      table_tr.push(record)
    }
  }
```
↓
■JavaScriptで、ボタンを押した行の**インデックス**を取得する
■JavaScriptで、取得したテーブルの全情報から、インデックスを参照して、**押した行の情報**を取得する

```javascript
  // ボタンを押したときに呼ばれる
  $(function(){
    $('button').on('click',function(){

      // 押したボタンの行番号を取得
      var idx=$(this).closest('tr').prop('rowIndex');

      // 先ほど取得したテーブルの全情報から、インデックスを参照して、押した行の情報を取得する
      // 行で取得した情報では文字型のため、数の型に変更
      event_category_id = Number(table_tr[idx][0])
      event_category_name = table_tr[idx][1]

      // このHTMLファイル内のhiddenタイプに値渡し
      document.getElementById('get_event_category_id').value = event_category_id
      // モーダルで表示させるためのテキスト
      document.getElementById('get_event_category_name').innerHTML = event_category_name
    });
  });
```
↓
■HTMLで、モーダルを出す & モーダル上の削除ボタンを押して「削除」が実行される手前までを行う
※bootstrapを使用しているため、class名等がbootstrap用です。

```html
    <div id="list_area" class="base_pattern">
      <div id="output_list_table">
        <table border="1" id="targetTable">
          <tbody>
            <tr>
              <th class="customer_account">イベントカテゴリid</th>
              <th class="action_button">イベントカテゴリ名</th>
              <th class="detail_button">詳細</th>
            </tr>
            <!-- pythonフレームワークのFlaskを使用しているため下記表記でfor文を使用しています -->
            {% for event_category in mst_event_category %}
              <tr>
                <form method="post">
                  <td class="event_category_id">{{ event_category.event_category_id }}</td>
                  <td class="event_category_name">{{ event_category.event_category_name }}</td>

                  <!-- hidden属性の項目 -->
                  <input name="event_category_id" type="hidden" value="{{ event_category.event_category_id }}">
                  <input name="event_category_name" type="hidden" value="{{event_category.event_category_name}}">

                  <td class="action_button">
                    <input type="submit" formaction="{{ url_for('ここはルーティング先のメソッド名を入れています', mode='update') }}" class="half_button" value="変更" />
                    {% if event_category.isDeletable == True %}
                    
                      <!-- ↓ここからモーダルを表示させるためのコードを追加しています！ -->
                      <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteModal" 
                      name="event_category_id" value="{{ event_category.event_category_id }}" style="padding: 2px 5px;">削除</button>
                    {% endif %}
                  </td>
                    <!-- ボタンクリック後に表示されるモーダル画面の内容 -->
                    <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="basicModal" aria-hidden="true">
                      <div class="modal-dialog">
                          <div class="modal-content">
                              <div class="modal-header" role="document">
                                  <h4 class="modal-title" id="deleteConfirmModalLabel">削除確認画面</h4></h4>
                              </div>
                              <div class="modal-body">
                                  <label>本当に「<label id="get_event_category_name"></label>」を削除しますか？</label>
                              </div>
                              <div class="modal-footer">
                                  <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>


                                  <!-- ↓ここからがモーダル上の削除ボタンを押したときに反応するコードです！ -->
                                  <form method="post"> 
                                    <input id="get_event_category_id" type="hidden" name="event_category_id" value="">    
                                    <button type="submit" formaction="{{ url_for('ここはルーティング先のメソッド名を入れています', mode='delete') }}" class="btn btn-warning">確定</button>
                                  </form>
                                  <!-- ↑ここまでがモーダル上の削除ボタンを押したときに反応するコードです！ -->


                              </div>
                          </div>
                      </div>
                  </div>
                  <!-- ↑ここまでがモーダルを表示させるためのコードです！ -->
                </form>
              </tr>
            {% endfor %}
          </tbody>
        </table>
      </div>
    </div>
```


これを書けば、本記事のゴールであった削除する手前までが完成です！！
読んでいただきありがとうございました！


## 4. 参考にしたサイト

テーブルのボタンから行インデックスを取得
https://teratail.com/questions/350535


JSの変数を、htmlのinputタグのvalueにセット
https://algorithm.joho.info/programming/javascript/image-processing-js-2/

JS テーブルの情報をセルごとに取得(for文2重ループ)
https://pg-happy.jp/javascript-table.html