Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Trying to add jQuery and AJAX to Odot "mark complete" and "mark incomplete" links?

In the Odot application, I have 'mark complete' and 'mark incomplete' links on 'ideas'. I would like to toggle them without page reload.

Here is my current code:

In the _idea.html.erb partial, which is under projects/idea.html.erb:

    <li id="<%= dom_id(idea) %>">
        <%= idea.description %>
        <%= link_to (idea.completed? ? 'Incomplete' : 'Complete'), complete_project_idea_path(idea.project, idea), method: :patch, remote: true, id: 'toggle_completion_link' %>
     </li>

Here is my controller action (I'm using nested resources):

    def complete
      @project = Project.find(params[:project_id])
          @idea = @project.ideas.find(params[:id])
        respond_to do |format|
          @idea.toggle_completion!
             format.html {redirect_to root_path}
             format.js { }
        end
    end

And in the idea.rb model:

    def completed?
       !completed_at.blank?
    end

    def toggle_completion!
        if completed?
             update_attribute(:completed_at, nil)
        else
             update_attribute(:completed_at, Time.now)
        end
    end

And here is my complete.js.erb file;

        $("#toggle_completion_link").text("<%= @idea.completed? ? 'Incomplete' : 'Complete' %>")

I also tried putting the link_to in new partials, but that became too complicated (because they were sub partials) and didn't work either.

My above code is not working, what should I try in my complete.js.erb file?

Good question. I'm planning to implement ajax in my own odot once I'm done with my ajaxified Treebook. Maybe you will find some parts of my code helpful: https://github.com/mczuchnowski/treebook (creating new status, editing status, upvoting and downvoting are ajaxified with jquery as remote: true links; link to live demo is in the readme)

I will let you know when I manage to do this for Odot. First thing that comes to my mind is the id of your html elements. I don't think it can work if every single link item has id: 'toggle_completion_link'. There should be only one element with given ID on the whole page.

Your Odot seems to be different than mine. What is the last stage you completed? Can you link your code? If you finish the whole Odot app (and it takes whole 8 courses on Trehouse, starting with "Build a Todo List Application with Rails 4" and ending with "Polishing Ruby on Rails", the final product should look like this: https://vast-sierra-1767.herokuapp.com/ ) all it should take is changing the class of the clicked element and firing "toggle completon".

Thanks for your reply! The latest tutorial I did was "Toggling Todo Item Completion" on "Rails Layouts and CSS Frameworks". I will now check the "ruby on rails forms" section.

You are right, the problem is probably that I don't have a given ID for each element.

1 Answer

So one thing I noticed is this:

$("#toggle_completion_link")

If I understand your code correctly, there will be many of these "ideas" on a page, based on this in your partial:

<li id="<%= dom_id(idea) %>">

The issue is that in your each of those links will have an ID of #toggle_completion_link. Which means there will be more than one on the page.

Instead, I would do this in your partial (adding the idea id to the toggle_completion_link ID):

<li id="<%= dom_id(idea) %>">
        <%= idea.description %>
        <%= link_to (idea.completed? ? 'Incomplete' : 'Complete'), complete_project_idea_path(idea.project, idea), method: :patch, remote: true, id: 'toggle_completion_link_#{idea.id}' %>
     </li>

Then in your js.erb file, you can call:

$("#toggle_completion_link_" + <%= idea.id %>)

Which will target the exact toggle button to perform the JS you have in your file.

Hope that makes sense! Happy coding =)

Thank you, Brandon!