Targeting css class of one single variable in embedded ruby loop using coffeescript - ruby-on-rails

My apologies for the confusing title. I am not very sure how to describe this question, please suggest alternative titles if possible!
I'm building a web app where you can like an answer, like most social apps. The problem is, I am new to using coffeescript and erb, so I am not sure how to target my jQuery animations to specific elements.
So my html.erb file looks like this. It has a ERB loop where I go through each answer and display it.
<% #question.answers.each do |answer| %>
<div class="row">
<div class="col-lg-2 col-sm-2">
<div class="like">
<button class="heart-btn">
</button>
<div class="liked">
+1
</div>
</div>
<div class="option">
<a href='/'>Report</a>
<br><a href='/'>Edit</a>
<br>
<%= link_to 'Delete', question_answer_path(#question, answer), method: :delete, data: { confirm: 'Are you sure?' } %>
</div>
</div>
<div class="col-lg-10 col-sm-10">
<div class="row" style="margin:0">
<!-- USER PROFILE -->
<a href='/users/2/profile'>
<div class="mini-profile">
<%= image_tag(#tutor.picture_url) %>
<ul style="list-style-type:none">
<li class="username"><%= #tutor.username %></li>
<li><i class="fa fa-flag" style="padding: 2px"></i><%= #tutor.country %></li>
<li><i class="fa fa-graduation-cap"></i><%= #tutor.educational_level %></li>
</ul>
</div>
</a>
</div>
<div class="row">
<div class="ans-box">
<ul style="list-style-type:none">
<li><strong>This answer was written on:</strong> <%= answer.created_at %></li>
<li class="ans-content"><strong>This is my answer:</strong> <%= raw answer.answercontent %></li>
</ul>
</div>
</div>
</div>
</div>
<hr class="line">
<% end %>
Now, for the div of class 'like', I have the following js written (document ready omitted):
# Heart like
$(".heart-btn").click ->
$(this).toggleClass('clicked')
$(".liked").show().fadeOut(500)
the 'liked' class is the +1 that will show when the heart is clicked.
But as you can probably imagine, this makes ALL the hearts on the page display the '+1'. I want to target only the 'heart' of the 'answer' that was clicked. I reckon I can do this by referencing the current 'answer' as a dom object, but I am unsure on how to do this. My attempt is doing something like:
# Heart like
current_ans = <%= answer %>
$(".heart-btn").click ->
$(this).toggleClass('clicked')
current_ans.$(".liked").show().fadeOut(500)
But the syntax seems very off to me and it doesn't seem to work.
(I think partially I'm not finding the solution because I cannot phrase my question so well. Please advise if this is the case. Thanks!)

jQuery closest is ideal for this:
$(".heart-btn").click ->
$(this).toggleClass('clicked')
$(this).closest('.like').find(".liked").show().fadeOut(500)

Related

Is there a conflict with this code and FancyBox3?

Can anyone tell me whats wrong with this section of code? I recently got this to work, but found out soon after the functionality for the Fancybox gallery stopped working. The a link element is only a sliver compared to the over all element. Im not sure if thats it. I know the most recent edit I made was to fix the surrounding row from .row-fluid to .row since that broke my layout. Below is the code:
<body id="portfolio">
<div class="container-fluid" id="particles-js"></div>
<%= render 'layouts/altmenu_gallery' %>
<h1>Portfolio</h1>
<div id="gallery" class="container-fluid">
<% #photos.each_slice(4) do |group| %>
<div class="row ">
<% group.compact.each do |photo| %>
<div class= "col-md-3">
<a class="fancybox" data-fancybox="gallery" href="<%=image_path photo.file_url %>" data-caption="<%= photo.description %>">
<%= image_tag photo.file_url, class:' img-fluid img-thumbnail' if photo.file.present? %>
</a>
</div>
<% end %>
</div>
<% end %>
<br class="clear">
</div>
<%= link_to 'New Photo', new_photo_path %>
</body>
Sorry, but it is not possible to tell without seeing the actual html code or, preferably, live demo. Maybe this issue arises because you have not escaped photo.description and that breaks html code, but, as I said, I can not be sure.

RSpec + Capybara scoping returns unexpected results

I have two tables: Suggestions and Keywords.
I'm trying to test removal of items from Keywords (which puts it into Suggestions automatically).
Here's my test:
it "removes a chosen keyword" do
page.first(:link, "Add").click
within(:css, "#keywords") do
find('li:nth-child(1)').click_link('X')
expect(page).to have_no_content(item.search.term)
end
end
It results in:
1) New collection Suggestions removes a chosen keyword
Failure/Error: expect(page).to have_no_content(item.search.term)
expected not to find text "Gift for her" in "Keywords\nGift for her X"
# ./spec/features/collections_spec.rb:60:in `block (4 levels) in <top (required)>'
# ./spec/features/collections_spec.rb:53:in `block (3 levels) in <top (required)>'
Here's the print of the body element:
<div class="col-lg-5 col-md-6 mb-4" id="suggestions">
<div class="card h-100">
<div class="card-body">
<h4 class="card-title">Suggestions</h4>
<p class="card-text">
<ul class="list-group list-group-flush" id="suggestion-list">
<li class="list-group-item">
Gift for her
<a class="btn btn-primary" rel="nofollow" data-method="post" href="/collections/1/item/choose.1">Add</a><a class="btn btn-primary" rel="nofollow" data-method="post" href="/collections/1/item/destroy.1">X</a><br>
</li>
</ul>
</p>
</div>
</div>
</div>
<div class="col-lg-5 col-md-6 mb-4" id="keywords">
<div class="card h-100">
<div class="card-body">
<h4 class="card-title">Keywords</h4>
<p class="card-text">
<ul class="list-group list-group-flush" id="keyword-list">
</ul>
</p>
</div>
</div>
</div>
And my show.html.erb file:
<div class="col-lg-5 col-md-6 mb-4" id="suggestions">
<div class="card h-100">
<div class="card-body">
<h4 class="card-title">Suggestions</h4>
<p class="card-text">
<ul class="list-group list-group-flush" id="suggestion-list">
<% if #suggestions %>
<% #suggestions.each do |s| %>
<li class="list-group-item">
<%= Hpricot.uxs s.search.term %>
<%= link_to 'Add', collection_item_choose_path(#collection, s),{ method: :post, class: "btn btn-primary" } %><%= link_to 'X', collection_item_destroy_path(#collection, s),{ method: :post, class: "btn btn-primary" } %><br>
</li>
<% end %>
<% end %>
</ul>
</p>
</div>
</div>
</div>
<div class="col-lg-5 col-md-6 mb-4" id="keywords">
<div class="card h-100">
<div class="card-body">
<h4 class="card-title">Keywords</h4>
<p class="card-text">
<ul class="list-group list-group-flush" id="keyword-list">
<% if #keywords %>
<% #keywords.each do |s| %>
<li class="list-group-item">
<%= Hpricot.uxs s.search.term %>
<%= link_to 'X', collection_item_remove_path(#collection, s),{ method: :post, class: "btn btn-primary" } %><br>
</li>
<% end %>
<% end %>
</ul>
</p>
</div>
</div>
</div>
Seems to me like the scoping is off somehow, although I checked and the link does actually click (you can see it in the puts page.body). Any ideas?
Thanks in advance!
This is unlikely to be a scoping issue since the reported text is "Keywords\nGift for her X" - whereas if it were seeing the text in the "suggestions" section if would have "Add" text in there too.
More likely is the clicking on the 'X' just isn't getting processed by your app due to an error somewhere. Check your test.log to see exactly what methods are being called, and whether there are errors.
Additionally you don't mention what driver you're using with Capybara. If you're using a JS capable driver it's possible you don't have Capybara.default_max_wait_time set high enough for the hardware you're testing on and/or turbolinks (assuming you have that in your app) is getting involved. Again, looking at your test.log should give a better idea of what's actually happening. Another to try would be to use save_and_open_screenshot to get an image of what the actual page looks like (assuming you're using a driver that supports it)
If you're not using a JS capable driver (ie you're using rack_test) then it's possible you haven't required capybara/rails and the method of the links isn't being used. Again, checking test.log will show the method (get vs post) being used for each request.

How can I call a link_to helper method in a block, linking to an image file while using a class as well?

This code is one element of a gallery. The "a href" tag is crucial for making it possible to expand an image by clicking on it. It is important that I have "a href" otherwise the javascript plugin (magnific-popup) won't work.
<a href="app/assets/images/1-fullsize.jpg" class="portfolio-box">
<img src="app/assets/images/1-thumbnail.jpg" class="img-responsive" alt="">
<div class="portfolio-box-caption">
<div class="portfolio-box-caption-content">
<div class="project-category text-faded">
Category
</div>
<div class="project-name">
Project Name
</div>
</div>
</div>
</a>
So far I came up with this:
<a href="app/assets/images/1-fullsize.jpg" class="portfolio-box">
<%= image_tag("1-thumbnail.jpg", alt: "", :class => "img-responsive") %>
<div class="portfolio-box-caption">
<div class="portfolio-box-caption-content">
<div class="project-category text-faded">
Category
</div>
<div class="project-name">
Project Name
</div>
</div>
</div>
</a>
So the images are visible but the the expanding of the picture is obviously not working in Rails. I thought about implementing an link_to helper method inside a block. But I have no idea how I can use the link_to helper method, link it to a file and additionally giving it a class inside a block? Is there a different solution? Does someone have any hints? If you need further information just let me know?
How can I call a link_to helper method in a block, linking to an image file while using a class as well?
You can use the the image_path as second option of link_to.
In Example:
<%= link_to(image_path("1-fullsize.jpg"), class: "portfolio-box") do %>
<%= image_tag("1-thumbnail.jpg", alt: "", :class => "img-responsive") %>
<div class="portfolio-box-caption">
<div class="portfolio-box-caption-content">
<div class="project-category text-faded">
Category
</div>
<div class="project-name">
Project Name
</div>
</div>
</div>
<% end %>
http://apidock.com/rails/ActionView/Helpers/AssetTagHelper/image_path
http://apidock.com/rails/ActionView/Helpers/AssetTagHelper/image_tag
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to

Interpolation of a Ruby string as an ID

I am trying to grasp interpolation and am trying to use a dynamic string ( i say dynamic as it can change all the time, I am pulling dates via a screen scrape for movie releases) and as an ID so that i can use bootstrap scrollspy in my project
I created a js fiddle using conventional ID's and anchor tags that demonstrates what I am trying to achieve.
As you can see, I would like to show the release date of a film if I am within that section as I am scrolling.
My code looks like this:
<div class="container">
<div class="row">
<div class="span8 offset2">
<div id="dateNav">
<ul class="dateNav">
<li><% #response.each_pair do |date, movie| %><%= link_to date_format(date) %><% end %></li>
</ul>
</div>
</div>
</div>
</div>
<div class="span9">
<% #response.each_pair do |date, movie| %>
<h3 class="resultTitle fontSize13" id="<%= date %>">Available on <%= date_format(date) %></h3>
</div>
<!-- More movie information here
<% end %>
I have my body set like so
<body data-spy="scroll" data-target="#dateNav">
and am calling scrollspy like so
$('.dateNav').scrollspy()
When you are in the relevant section the date is supposed to appear
CSS
ul.dateNav ul li a {
display:none;
}
ul.dateNav ul > li.active > a{
display:block
color: red;
text-decoration: underline;
}
however when scrolling down the page the dates do not appear.
Any help appreciated, would really like to clarify some understanding here.
Thanks
EDIT
ok so have changed as Joe Pym suggested
<li><% #response.each_pair do |date, movie| %><%= link_to date_format(date), "##{date}" %><% end %></li>
Each date has its own id now which wasnt happening before but still no appearance of the relevant date
HTML now generated
<ul class="dateNav">
<li>
9th Jan 2013
11th Jan 2013
18th Jan 2013
23rd Jan 2013
25th Jan 2013
30th Jan 2013
</li>
</ul>
EDIT for Sara
calling scrollspy
$('#spyOnThis').scrollspy();
Nav for dates
<div class="container">
<div class="row">
<div class="span12">
<div id="dateNav">
<ul class="nav dateNav">
<li><% #response.each_pair do |date, movie| %><%= link_to date_format(date), "#d_#{date}" %><% end %></li>
</ul>
</div>
</div>
</div>
List of Movies
<div id="spyOnThis">
<% #response.each_pair do |date, movie| %>
<h3 class="resultTitle fontSize13" id="d_<%= date %>">Available on <%= date_format(date) %></h3>
<% movie.each do |m| %>
<div class="thumbnail clearfix">
<img class="pull-left" src=<% if m.image_link %> <%= m.image_link %> <% else %> "/assets/noimage.jpg" <% end %>>
<div class="caption pull-right">
<%= link_to m.name, m.title_id, :class => 'resultTitle fontSize11' %>
<p class="bio"><%= m.bio %></p>
<p class="resultTitle">Cast</p>
<p class="bio"><%= m.cast.join(", ") unless m.cast.empty? %></p>
<%= link_to "Remind me", reminders_path(:title_id => m.title_id), :method => :post, :class => 'links button' %>
</div>
</div>
<% end %>
<% end %>
</div>
CSS
#spyOnThis {
height:auto;
overflow:auto;
}
I set height as auto because the number of results can change every time
ul.dateNav > li.active > a {
display:block;
color: red;
text-decoration: underline;
}
IDs that start with a number are invalid. Source
Try adding a string constant to the beginning of each ID.
and
<h3 class="resultTitle fontSize13" id="d_<%= date %>">
Disclaimer: I don't know Ruby.
EDIT
Okay, so I stripped this down and got it working. jsFiddle
I changed some of your classes and IDs for fiddle purposes (also there seemed to be some confusion about .dateNav and #dateNav), but it should look something like this:
<ul class="nav dateNav">
<li>
<% #response.each_pair do |date, movie| %><%= link_to date_format(date) %><% end %>
</li>
</ul>
and
<div class="span9">
<% #response.each_pair do |date, movie| %>
<h3 class="resultTitle fontSize13" id="d_<%= date %>">Available on <%= date_format(date) %></h3>
</div>
You can put the IDs on div (like in the fiddle) or h3, it doesn't matter. The important part is the CSS and how you initiate ScrollSpy.
If you're calling it with JavaScript ($('#spyOnThis').scrollspy()), you need to attach it to the element that is going to trigger scroll events - not the menu that keeps track. Source
Furthermore, you should remove data-spy and data-target from the body element.
Last but not least, the element you're calling .scrollspy() on needs to have a height and overflow: auto; set for the plugin to keep track of the scroll position.
In your ERB, where you have
<li>
You aren't interpolating it. Change it to:
<li>
EDIT.
Scrap that...just looks like that a tag should be inside the loop?

How do I add left and right classes to every other element in a loop in Ruby on Rails?

I am working within a Ruby on Rails app. I have a loop that creates divs like this:
<% #snorks.each do |snork| -%>
<div>
<%= snork %>
</div>
<% end %>
And I need the output to have every other div be floated left or right like this:
<div class="left">
Allstar Seaworthy
</div>
<div class="right">
Casey Kelp
</div>
<div class="left">
Dimmy Finster
</div>
<div class="right">
Daffney Gillfin
</div>
<div class="left">
Tooter Shellby
</div>
<div class="right">
Dr. / Uncle Galeo
</div>
Additionally, I need to add a div with class="clear" every two divs, like this:
<div class="left">
Allstar Seaworthy
</div>
<div class="right">
Casey Kelp
</div>
<div class="clear"></div>
<div class="left">
Dimmy Finster
</div>
<div class="right">
Daffney Gillfin
</div>
<div class="clear"></div>
<div class="left">
Tooter Shellby
</div>
<div class="right">
Dr. / Uncle Galeo
</div>
<div class="clear"></div>
I have researched, and found a few posts saying that the alternate classes can be accomplished easily by using cycle(), and that does work. However, when I use it in two places within the loop it stops working right and just outputs something like this:
<div class="left">
Allstar Seaworthy
</div>
<div class="left">
Casey Kelp
</div>
<div class="left">
Dimmy Finster
</div>
<div class="left">
Daffney Gillfin
</div>
<div class="left">
Tooter Shellby
</div>
<div class="left">
Dr. / Uncle Galeo
</div>
What's the best practices way in Ruby on Rails to alternate classes in a loop, and also add something every other loop?
According to the documentation, if you need nested ones you name them. Otherwise they will both share the name "default" and conflict.
<% #snorks.each do |snork| -%>
<div class="<%= cycle('left', 'right') -%>">
<%= snork %>
</div>
<%= cycle('','<div class="clear"></div>', :name=>"cleardiv") %>
<% end %>
The best thing here seems to be using each with index. That way you could do some simple modulus math to determine if the number is odd or even and output the correct class and add the clears.
#snorks.each_with_index do | snork, index|
If index%2 == 0
class = 'left'
else
class = 'right'
end
Well u get my drift and I'm on my phone.
use cycle helper
http://apidock.com/rails/ActionView/Helpers/TextHelper/cycle
<% #snorks.each do |snork| -%>
<div class="<%= cycle("left", "right") -%>">
<%= snork %>
</div>
<% end %>
Edit: for adding new div; following could help
<% #snorks.each_slice(2) do |snork_batch| -%>
<% snork_batch.each do |snork|%>
<div class="<%= cycle("left", "right",:name=>"className") -%>">
<%= snork %>
</div>
<%end%>
<div class="clear"></div>
<% reset_cycle("className")%>
<% end %>

Resources