mizukosy
@mizukosy

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【Rails】eachで取り出した全てのカラムに、それぞれjavascriptの処理をかけたい

Railsでeachで取り出した全てのカラムに、それぞれjavascriptの処理をかけたい

Railsを使用し、単語帳風アプリを作成しています。
indexアクションに問題一覧を表示させ、問題をクリックすると解答が表示される仕様を目標としています。

indexアクションで、userが作成した全ての単語の問題と解答を取り出し、問題は表示・解答はCSS(visibility: hidden;)にて非表示にしています。
解答のdivに付与したidより、java scriptを活用してvisibilityをvisibleへと変更する関数を作成しました。
1つ目の問題にはその処理が実施されますが、それ以降は処理されません。
forEachを活用する事を試みましたが、そもそも配列ではないため下記のエラーが生じています。

Railsでeachにて取り出した全てのカラムに対し、javascriptの処理を施す事ができるでしょうか?

ruby 2.6.5
Rails 6.0.0

発生している問題・エラー

console.
answer.js:6 Uncaught TypeError: questionBtn.forEach is not a function

該当するソースコード

app/views/questions/index.html.erb
<div class="q-a-index" >
  <% @question.each do |q| %>
     <% if user_signed_in? && q.user_id == current_user.id %>
      <div class="q-a-tag" id="question" >
         <div class='question-tag' >
           問題:<%= q.question %>
         </div>
         <div class='answer-tag', id="answer" >
           答え:<%= q.answer %>
         </div>
      </div>
     <% end %>
   <% end %>
</div>
app/javascript/answer.js
function answer(){

  const questionBtn = document.getElementById("question")
  const answerOpen = document.getElementById("answer")

  questionBtn.forEach(function(question){
    questionBtn.addEventListener("click", function() {
      if (answerOpen.getAttribute("style") == "visibility:hidden;") {
        answerOpen.setAttribute("style","visibility:visible;")
      } else {
        answerOpen.setAttribute("style", "visibility:hidden;")
      }
    })
   })
}
window.addEventListener('load', answer);

自分で試したこと

  • forEachを試みましたが、そもそもeach内のidのため、当然の様に上記のエラーが生じました。
  • 最初の問題のみはforEachをなくす等にて処理できました。
  • divからリスト要素へ変更して実施する。(ulはeachの外、liはeach内に配置した状態でforEachを使用。)
0

1Answer

idはユニークである必要があり、1つのページに同じidは1つしかつけることができません。
また、idはユニークであるため、document.getElementByIdでは要素を1つしか取得することができず、要素の配列が帰ってきません。

そのため、document.getElementsByClassNameを使い、class名で要素を取得し、それぞれにイベントリスナーをつけるか、それぞれにidを割り当てるようにすると解決できそうな気がします。(実際に試してみていないです)

2Like

Comments

  1. @mizukosy

    Questioner

    ありがとうございます
    Javascriptの特性を把握する機会になりました。
    頂いたアドバイスを基に試行錯誤してみたのですが、consol.logなどを活用しながら行ってみるとconstで定義されていないために、
    Uncaught TypeError: questionBtn.forEach is not a function
    が生じ、解決できませんでした。
    show actionで問題-解答を一つに絞った状態での実装を試みます。
    回答頂き、勉強や励みになりました。ありがとうございます。
  2. 解決できてよかったです。
    引き続き頑張ってください!

Your answer might help someone💌