2
1

More than 1 year has passed since last update.

バリデーションが実行された後、jsが機能しない

Posted at

はじめに

本記事はプログラミング初心者が、railsの学習を進めながら、躓いた部分、解決した箇所、またそれらの解決方法を備忘録も兼ねてまとめているものです。
最初はprogate。そのあと、「現場で使える RubyonRails5 速習実践ガイド」(通称)「現場Rails」を参考に進めていきました。
そのため、記事の内容には誤りがある可能性があることをご理解ください。
誤りがあればお手数ですが、ご指摘いただければと思います。よろしくお願いします。

環境

Ruby 3.1.2
Rails 7.0.3.1

問題のエラー

バリデーションが実行された後に、jsが機能しなくなってしまった。
スクリーンショット 2022-08-21 23.01.24.png
スクリーンショット 2022-08-21 23.01.30.png
本来ならば、上記の二枚のようになり、判定を開始するボタンが押せるのですが、押して、バリデーションが実行された後、
スクリーンショット 2022-08-21 23.01.38.png
このように、ボタンが出てきません(jsが反映されていない。)

解決策

どうやら、turboにヒントが隠されているようです。最初のコードを見てみましょう。

check.js
document.addEventListener("turbo:load", function() {
 var allowCheckbox = document.getElementById("check");
 var checkbutton = document.getElementById("link3");

 allowCheckbox.addEventListener("change", function(event) {
  if (event.target.checked) {
    checkbutton.disabled = false;
  } else {
    checkbutton.disabled = true;
  }
 }, false);
})

一行目のturboは、ページをリロードした時に、もう一度jsが反映されるように記載しているものです。
しかしながら、バリデーションが実行された後は、コントローラーを見てみると、

user.controller
class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def create
   @user = User.new(user_params)
   if @user.save
    redirect_to @user, notice: "判定が正常に実行されました。"
   else
    render :new, status: :unprocessable_entity
   end
  end



  private
  def user_params
    params.require(:user).permit(:name, :sex, :age, :hemo, :feti, :sterone, :agreement)
  end
end

はい、新規登録画面にいくのに、renderになっています。
ここがポイントのようで、renderの場合でも、turboを使ってjsが反映できるようにすることができるようです。それが、以下

check.js
 document.addEventListener("turbo:render", function() {

上記のようにturbo:loadの他にturbo:renderを付け足すことで、renderされても、jsが反映されるようです。
出来上がったコードがこちら

check.js
document.addEventListener("turbo:load", function() {
 var allowCheckbox = document.getElementById("check");
 var checkbutton = document.getElementById("link3");

 allowCheckbox.addEventListener("change", function(event) {
  if (event.target.checked) {
    checkbutton.disabled = false;
  } else {
    checkbutton.disabled = true;
  }
 }, false);
})
 document.addEventListener("turbo:render", function() {
  var allowCheckbox = document.getElementById("check");
  var checkbutton = document.getElementById("link3");

  allowCheckbox.addEventListener("change", function(event) {
    if (event.target.checked) {
      checkbutton.disabled = false;
    } else {
      checkbutton.disabled = true;
    }
  }, false);
})

実際に、バリデーションが実行された後でも、jsは機能しました。

おわりに

今回は、バリデーションが実行された時に、どのようにその画面に遷移してるかがポイントでした。loadであれば、いつも通り、jsは機能していましたが、バリデーションでrenderにしていたので、もう一つjsのコードを追加する必要があったのですね。
これは、これから先も使いそうな予感(?)がするので、覚えておこうと思います。
なかなか、読みやすさというものに欠けるかもしれませんが、誰かの問題を解く鍵になれば嬉しいでです。
ありがとうございました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1