Show original photo on click Rails - javascript

Hi I am looping through uploaded photos and showing thumbnails. I'm trying to display the original photo when someone clicks on the thumbnail. The problem is that it only works on the first thumbnail in the loop. Do I need to give each thumbnail a individual id or how can I get it to work on every thumbnail? Any tips? :)
My show:
<% #project.assets.each do |asset| %>
<% if asset.photo.file? %>
<li class="thumbnail col-md-2">
<a id="thumb" href="#">
<%= image_tag asset.photo.url(:thumb) %>
</a>
</li>
<% end %>
<div id="popup">
<%= image_tag asset.photo.url(:original) %>
</div>
<% end %>
My javascript:
<script type="text/javascript">
$(document).ready(
function() {
$("#thumb").click(function() {
$("#popup").toggle();
});
});
</script>
Thanks :)

Try this :
<% #project.assets.each do |asset| %>
<% if asset.photo.file? %>
<li class="thumbnail col-md-2">
<%= link_to asset.photo.url(:original), class: :popup_link, target: :_blank do %>
<%= image_tag asset.photo.url(:thumb) %>
<% end %>
</li>
<% end %>
<% end %>
<div id="popup"></div>
<script type="text/javascript">
$(document).ready(function() {
$(".popup_link").click(function(e) {
e.preventDefault();
$("#popup").html( $('<img>').attr('src', this.href) );
});
});
</script>
what we're doing here is that on click, we fill the popup div with an image tag whose src attribute is the clicked link's href attribute value.
The good thing about this approach is that it degrades gracefully when javascript is desactivated (clicking on the link will open the full image in a new tab). As you don't load all full images (just to hide them), your page load time will likely decrease, too.

you have to use class "thumb" except id. because id is uniq so only first working.
the same with "popup" id because always will be show first image. so you can make like:
<% #project.assets.each do |asset| %>
<% if asset.photo.file? %>
<li class="thumbnail col-md-2">
<a id="asset-#{asset.id}" class="thumb" href="#">
<%= image_tag asset.photo.url(:thumb) %>
</a>
</li>
<% end %>
<div id="popup-asset-#{asset.id}">
<%= image_tag asset.photo.url(:original) %>
</div>
<% end %>
<script type="text/javascript">
$(document).ready(
function() {
$(".thumb").click(function() {
$("#popup-" + this.attr("id")).toggle();
});
});
</script>

Related

How to combine Rails tag and JavaScript

I have 4 modals on 1 page, each modal has to show product images belonging to a different product. I thought I could use the product.id so that javascript knows which product images to show, but I'm not sure how to achieve this.
In my rails I thought I could do:
class="mySlides<%= product.id %>"
And then in Javascript I did:
getElementsByClassName(`mySlides<%= product.id %>`);
But it doesn't work properly. Javascript always grabs the last product.id on the page. How do I correctly insert the <%= product.id %> into a javascript function??
Part of my view:
<div id="myModal<%= product.id %>" class="productsModal">
<div class="modal-content">
<% product.product_images.each.with_index do |product_image, index| %>
<div class="mySlides mySlides<%= product.id %>">
<%= image_tag product_image.image.url(:large) %>
</div>
<% end %>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
<% product.product_images.each.with_index do |product_image, index| %>
<div class="column">
<div style="width:100%" onclick="currentSlide(<%= index+1 %>)" class="demo demo<%= product.id %>">
<%= image_tag product_image.image.url(:thumb) %>
</div>
</div>
<% end %>
</div>
Part of JavaScript:
function showSlides(n) {
var slides = document.getElementsByClassName(`mySlides<%= product.id %>`);
var dots = document.getElementsByClassName(`demo<%= product.id %>`);
...
}
if your javascript is in a separate file, you can add the template handler .erb: myfile.js.erb to use embed ruby
if your javascript is inside your html view, you can use the rails javascript_tag helper (instead of <script></script>):
<%= javascript_tag do %>
var slides = document.getElementsByClassName('mySlides<%= j product.id %>');
var dots = document.getElementsByClassName('demo<%= j product.id %>');
<% end %>

Div clickable in Rails with jQuery?

I have a div in one of my Rails views that I would like to make fully clickable:
<% #objects.each do |f| %>
<div class="overlay" >
<%= link_to image_tag("play.png"), f %>
</div>
How would I make the div class overlay follow the link_to the |f| object in jQuery? I found this in another StackOverflow question and I would like to customize it for the above scenario:
$('.overlay').click( function(event) {
var clicked_div = $(this);
# do stuff with the event object and 'this' which
# represent the element you just clicked on
});
Thanks!
Have you tried giving a class to the a tag?
<% #objects.each do |f| %>
<%= link_to image_tag("play.png"), f, class: 'overlay' %>
...
<% end %>
This will end up creating something like
<a href='/some_address' class='overlay'><img src="play.png" alt="something" /></a>

Jquery mobile navbar not active after session log in (Rails)

1) This is my Login page:
<% provide(:title, 'Sign In') %>
<div data-role="page" data-url="/signin/">
<h1>Sign In</h1>
<%= form_for(:session, url: sessions_path) do |f| %>
<div>
<%= f.text_field :username_or_email, placeholder: "username or email", autofocus: true %>
</div>
<div>
<%= f.password_field :password, placeholder: "password" %>
</div>
<div>
<%= f.submit "Sign In", rel: "external" %>
</div>
<% end %>
</div>
2) This is my Home page after login:
<% provide(:title, #user.name) %>
<div data-role="page" id="home" data-url="/users/<%= #user.id %>/" >
<div data-role="header">
Menu
<h4>Home</h4>
<%= link_to 'New', new_pin_path, rel: "external" %>
</div>
<% if !#user.pins.any? %>
<h3>Welcome to Pins!... Enter your first pin.</h3>
<% end %>
<%= render #user.pins %>
</div>
<div data-role="page" id="menu">
<div class="ui-grid-a center">
<div class="ui-block-a menublock">
Home
</div>
<div class="ui-block-b menublock">
<%= link_to 'Friends Pins', pins_path %>
</div>
<div class="ui-block-a menublock">
<%= link_to 'Settings', edit_user_path(current_user) %>
</div>
<div class="ui-block-b menublock">
<%= link_to "Sign Out", signout_path, method: "delete" %>
</div>
</div>
</div>
So basically, after I log in and try clicking on Menu I get no response (unless I refresh the page).
3) This is how my session login works:
I was going to paste it but it's super long, I basically used the same thing that is going on here:
http://ruby.railstutorial.org/chapters/sign-in-sign-out#top
4) Trailing slashes (this is a requirement by jQuery Mobile): I thought my problem may be because I did not have trailing slashes set on all the urls, so I added this to my application.rb: config.action_controller.default_url_options = { :trailing_slash => true } And although it fixed a lot of the navigation between pages, it does not fix the issue after my session log in.
5) Also note that when I refresh the home page after login, the navbar does work correctly.
You are missing a "data-rel" tag. Try the following:
Menu

dynamic page caching in rails

How to add dynamic caching to time or I should use fragment caching?
I tried to follow RailsCasts but nothing works.
_feed.html.rb
<% cache feed do %>
<div class="feed">
<div id="time">
<%= render 'shared/time' unless #page_caching %>
</div>
<p class="pull-right grey"><%= time_ago_in_words(feed.posted_at) %></p>
<div class="clearfix">
<p class="grey"><%= image_tag feed.profile_pic, :class => 'pic', :size => '15x15' %> #<%= feed.name %></p>
</div>
<p class="content"><%= raw auto_link(feed.content, :username_include_symbol => true, :target => '_blank') %></p>
</div>
<% end %>
_time.html.rb
<p class="pull-right grey"><%= time_ago_in_words(feed.posted_at) %></p>
index.js.rb
$('#feeds').append('<%= j render(#feeds) %>');
<% if #feeds.next_page %>
$('.pagination').replaceWith('<%= j will_paginate(#feeds) %>');
<% else %>
$('.pagination').remove();
<% end %>
$('#time').prepend('<%= j render("shared/time") %>');
feeds_cotroller.rb
def index
#page_caching = true
#feeds = Feed.page(params[:page]).per_page(12)
end
using helpers that changes over time should not be used inside a cache block. The best solution to this is to use a js plugin that will insert the time string for you. google for timeago js plugin and you'll get a bunch of useful results. The first result there is in http://timeago.yarp.com/. Using that plugin, your code should look like the following (i've inserted a script which should insert the time string)
<% cache feed do %>
<div class="feed">
<div id="time">
<%= render 'shared/time' unless #page_caching %>
</div>
<p class="pull-right grey timeago" title="<%= feed.posted_at %>"></p>
<script>
jQuery(document).ready(function() { jQuery("p.timeago").timeago() })
</script>
<div class="clearfix">
<p class="grey">
<%= image_tag feed.profile_pic, :class => 'pic', :size => '15x15' %> #<%= feed.name %>
</p>
</div>
<p class="content"><%= raw auto_link(feed.content, :username_include_symbol => true, :target => '_blank') %></p>
</div>
<% end %>
This is a simple implementation. You probably want to move the js call to an asset file so you dont have to call it inside the cache. Anyway, this should give you an idea.

Hiding a div when mouse is clicked on any part of the page, other than the div

Currently, I have a button called 'Comment' that when clicked slides down a comment box. I want the comment box to hide whenever the user clicks on any area of the page other than the comment box itself.
Currently, with my code the button just disappears when it is clicked. Could anyone point me in the right direction? Thanks!
Ruby ERB:
<% #entry.each do |e| %>
<div class="entry">
<p><%= e.entry %></p>
<small>Posted by <%= e.author %> at <%= e.created_at.strftime("%I:%M%p %m/%d/%Y") %></small>
<% if e.comments.nil? %>
<p>No Comments</p>
<% else %>
<% e.comments.each do |c| %>
<div class="comment">
<blockquote><strong><%= c.author %></strong> writes:<%= c.comment %></blockquote>
</div>
<% end %>
<% end %>
<div class="comments">
Comment
<div class="newcomment" id="comment<%= e.id %>">
<%= form_for #comment, :url => entry_comments_path(e, #comment) do |f| %>
<ol>
<li><%= f.label :author %>
<%= f.text_field :author %></li>
<li><%= f.label :comment %>
<%= f.text_area :comment %></li>
<%= f.submit %>
</ol>
<% end %>
</div>
</div>
</div>
<hr />
<% end %>
<%= button_to "Write A Message", new_entry_path, :method => :get %>
Javascript:
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
$(document).ready(function()
{
$('.newcommentbutton').click(function()
{
var button = $(this);
var comment = button.attr('data-comment');
button.hide();
$('#comment' + comment).slideDown('fast', function() {
$('#comment' + comment + ' input[type=text]').focus();
});
});
$('.newcomment').click(function(event)
{
event.stopPropagation();
});
$('body').click(function()
{
$('.newcomment').hide();
});
});
Your new comment buttons also needs to stop propagation, like this:
$('.newcommentbutton').click(function(e) {
var button = $(this);
var comment = button.attr('data-comment');
button.hide();
$('#comment' + comment).slideDown('fast', function() {
$('#comment' + comment + ' input[type=text]').focus();
});
e.stopPropagation();
});
You have the right idea, just remember that .newcommentbutton is also in <body> so it's opening the comment form, then the click bubbles up and closes it.
If you have a div like that:
<div id="comment"...>
You can put the focus on it, when you show it:
document.getElementById('comment').focus();
You need to set a tabindex attribute to your DIV to make the focus work:
<div id="comment" tabindex="99"...>
Then you set an onblur on it, and it will disappear, when the user click anywhere on the page:
document.getElementById('comment').onblur = function(){
this.parentNode.removeChild(this);
};

Categories