0

I'm trying to create a JS function to increment the count of the vote on the page, which I would usually do by writing Document.getElementByID and then writing in the ID, but in Rails, I am trying to figure out how to write this function where the table rows are being created dynamically in a loop. How would I create a function to do this?

Here's the html rails loop:

  <tbody>
    <% @requests.each do |request| %>
      <tr>
        <td><%= request.artist %></td>
        <td><%= request.title %></td>
        <td><%= request.voteCount %></td>
        <td><button onclick="upVote()">Vote</button></td>
      </tr>
    <% end %>
  </tbody>

1 Answer 1

1

You've got a few options: If you want to stick with your onclick handler, just pass the request ID to your upVote() function. That might look like this:

<td><button onclick="upVote(<%= request.id %>)">Vote</button></td>

Then, in your JS upVote(requestID) function, do whatever needs to be done to make that request and update your UI accordingly.

Another, superior, option would be to use Rails' built-in remote link_to helper, which is powered by rails-ujs. Here's how that might look:

<td><%= link_to 'Vote', [:upvote, request], remote: true, method: :post, class: 'upvote' %></td>

Note that I'm using the POST method, since actions that have side-effects should not be done with a GET request. Make sure you route accordingly.

Then in your RequestsController:

def upvote
  request = Request.find(params[:id])
  request.upvote! # Or do whatever you need to do to upvote it

  # Respond to your JS request with whatever updated info it might need to update the UI
  render json: { voteCount: request.voteCount } } 
end

Finally, in JS (written as CoffeeScript):

$('a.upvote').on 'ajax:success', (event) ->
  # Update your UI to reflect the upvote (you can access the JSON returned from your upvote action here to make necessary updates)
Sign up to request clarification or add additional context in comments.

7 Comments

In the first method you mentioned, how would I get the element in order to update? Heres my JS code function upVote(requestID) { var count = document.getElementsByClassName("voteCount")[0].innerHTML; count = parseInt(count); count = count + 1; count = count.toString(); document.getElementById("voteCount").innerHTML = count; document.getElementById("voteButton").disabled = "true"; }
One option would be to add a data-request-id attribute to maybe the <tr>, so something like: <tr data-request-id="<%= request.id %>">. Then in your JS, you could find it again with $("tr[data-request-id='" + requestID +"']"). But I'd strongly recommend checking out the rails-ujs approach.
Id like to try the Rails way but Im new to rails and I think im going to have a tougher time implementing it. Im trying it and getting an error undefined method upvote_request_path' for #<#<Class:0x00007f08348ab270>:0x00007f08348a8d68>`
the html is ` <tbody> <% @requests.each do |request| %> <tr data-request-id="<%= request.id %>"> <td style="text-align: center"><%= request.artist %></td> <td style="text-align: center"><%= request.title %></td> <td style="text-align: center" class="voteCount"><%= request.voteCount %></td> <td style="text-align: center"><button class = "voteButton" onclick="upVote()">Vote</button></td> <td><%= link_to 'Vote', [:upvote, request], remote: true, method: :post, class: 'upvote' %></td> </tr>`
You need to add a route for your upvote action. Check out the Routing guide. In general, the Rails guide are your friends. They are incredibly well written and informative - I'd encourage anyone new to Rails to at least skim them to get a sense for how the various components all fit together. guides.rubyonrails.org/routing.html#adding-more-restful-actions
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.