確認ダイアログに変数をぶち込む方法 rails + javascript

## やりたいこと

プロ野球の試合を予想するアプリを作っています。
以下の画像のように確認ダイアログに変数を表示したい。（下記画像のチーム名とスコアは変数である）
![https://i.gyazo.com/9fd0b8470b61681e0780fd3d441d61d8.png](https://i.gyazo.com/9fd0b8470b61681e0780fd3d441d61d8.png)
## やり方
Railsで確認ダイアログで変数を表示することはほぼ不可能らしい。よってJavaScriptに頼る。
しかしフォームを送信し保存する処理はRailsで書いた。
なのでフォーム送信はRailsで実装。確認ダイアログの表示はJavaScriptで実装していく。
## 手順

1. railsで確認ダイアログの表示設定を消す
2. JavaScriptで確認ダイアログを表示する
3. 送信ボタンにイベントを設定する
4. 確認ダイアログに変数を格納する
5. confirmメソッドの性質を理解する
6. 処理を分岐させる

## 1, railsで確認ダイアログの表示設定を消す
確認ダイアログはJavaScriptで表示するので`data: {confirm: “”}`の箇所は消す。
```ruby
<%= f.submit "投票する", class: 'btn btn-primary mb-3', data: { confirm: "送信してもいいですか？？" } %>
```

## 2, JavaScriptで確認ダイアログを表示する
erb内に埋め込んでいく。まず確認ダイアログを表示する関数`check_form`を定義。
```jsx
<script>
	function check_form() {
		window.confirm("送信してもいいですか？？")
};
</script>
```
confirmメソッドを使う。
これでひとまず確認ダイアログが表示される。

## 3, 送信ボタンにイベントを設定する
送信ボタンを押した時に`check_form`を呼び出すように設定する。
`onclick`オプションに`check_form`を指定。
```jsx
<%= f.submit "投票する", class: 'btn btn-primary mb-3', :onclick => "return check_form()" %>
```
## 4, 確認ダイアログに変数を格納する
「DeNA 3-0 中日で投票してもいいですか？」というように、確認ダイアログの中に変数を表示したい。
まず関数内で扱いたい変数を定義。
```jsx
<script>
	var first_base_side_pro_team = '<%= today_pro_game.first_base_side_pro_team %>';
  var third_base_side_pro_team = '<%= today_pro_game.third_base_side_pro_team %>';
  var first_base_side_score = document.getElementById('first_base_side_score').value;
  var third_base_side_score = document.getElementById('third_base_side_score').value;

	function check_form() {
		window.confirm(first_base_side_pro_team + ' ' + first_base_side_score + '-' + third_base_side_score + ' ' + third_base_side_pro_team + 'で投票してもいいですか？');
};
</script>
```
ポイントは二つ。
一つ目はJavaScript内にerbを埋め込んでいる。（JS内にrubyを埋め込む方法はこちら [https://qiita.com/masamitsu-konya/items/84ef7a63333b66713512](https://qiita.com/masamitsu-konya/items/84ef7a63333b66713512)）
二つ目はフォームに入力した値を取得している点。（フォームの入力値を取得する方法はこちら [https://www.javadrive.jp/javascript/form/index1.html#section2](https://www.javadrive.jp/javascript/form/index1.html#section2)）
フォームの入力値を取得するには、まず入力フォームを取得する必要がある。そのためにゅりょくフォームにid属性を持たせる。
```ruby
<%= f.number_field :first_base_side_score, id: 'first_base_side_score' %>
```
そしてその入力フォームを取得しvalueメソッドで、入力値を取得できる。
```jsx
var first_base_side_score = document.getElementById('first_base_side_score').value;
```
そしてconfirmメソッドの引数に定義した変数を使う。
**これでいけたと思ったら、確認ダイアログでキャンセルを押してもデータが送信されてしまう。これじゃ確認する意味がない。。。**
よってキャンセル選んだ時にフォームを送信しないようにする。

## 5, confirmメソッドの性質を理解する
キャンセルを選んだ時にフォームを送信しないようにするには、まずconfirmメソッドの性質を理解する必要がある。
confirmメソッドは確認ダイアログでOKを選択した場合trueを、キャンセルをクリックした場合はfalseを返す！これを知っておく。
よって**confirmメソッドの箇所を変数に置き換える**。これでもちゃんと確認ダイアログは出るので大丈夫。
```ruby
var submitMessage = window.confirm(first_base_side_pro_team + ' ' + first_base_side_score + '-' + third_base_side_score + ' ' + third_base_side_pro_team + 'で投票してもいいですか？');
```

## 6, 処理を分岐させる
「確認ダイアログでOKを押した時はform_withで値を保存する。キャンセルを押した時は何もしない。」を実装する。
```ruby
function check_form() {
  var first_base_side_pro_team = '<%= today_pro_game.first_base_side_pro_team %>';
  var third_base_side_pro_team = '<%= today_pro_game.third_base_side_pro_team %>';
  var first_base_side_score = document.getElementById('first_base_side_score').value;
  var third_base_side_score = document.getElementById('third_base_side_score').value;
  
  var submitMessage = window.confirm(first_base_side_pro_team + ' ' + first_base_side_score + '-' + third_base_side_score + ' ' + third_base_side_pro_team + 'で投票してもいいですか？');
  if (!submitMessage) {
    return false;
  };
};
```
「キャンセルを押した時は何もしない。」は`return false;`で実装できる。（詳しくはこちら [https://qiita.com/pakushiken/items/8fc41ed553b95142cff5](https://qiita.com/pakushiken/items/8fc41ed553b95142cff5)）

以上で完了。

## 参考にした記事
### 入力フォームの入力値を取得する方法
[テキストボックスの値をJavaScriptを使って取得・設定する](https://www.javadrive.jp/javascript/form/index1.html#section2)
### confirmメソッドの性質
[【JavaScript入門】confirmで「はい」「いいえ」のダイアログを出す | 侍エンジニアブログ](https://www.sejuku.net/blog/28217#confirm-2)
### javascriptにrubyを埋め込む
[html.erbファイルでjs直書きでその中にrubyのコードを埋め込んでいる状態のものをslimに置き換えるときの書き方 - Qiita](https://qiita.com/masamitsu-konya/items/84ef7a63333b66713512)
### form_withで値を送信する時、値がnilならクライアント側で送信を阻止する
[railsでsubmitをキャンセルする - Qiita](https://qiita.com/pakushiken/items/8fc41ed553b95142cff5)
### 選択肢がOKのみの確認ダイアログ
[OKボタン1つだけのアラートボックスを表示する方法 - JavaScript TIPSふぁくとりー](https://www.nishishi.com/javascript-tips/alert-dialogbox.html)