Div clickable in Rails with jQuery? - javascript

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>

Related

How to pass <li> elements to form in ruby on rails

Currently in my ruby on rails project, my events/new.html.erb looks like this:
<h2>Neuer Event</h2><br>
<div id="kalendi">
<%= render 'kalendi' %>
</div>
<ul class="lista">
</ul>
<%= simple_form_for(#event) do |f| %>
<%= f.input :name %>
<%= f.input :content %>
<%= f.input :date%>
<%= f.input :tag_list, as: :check_boxes, collection: ['Logik', 'Ethik', 'Metaphysik'] %><br>
<%= f.button :submit %>
<% end %>
<script>
$(document).ready(function(){
$(document).on('click', ".btn2", function () {
var buttonContent = $(this).html();
$(".lista").append("<li>" + buttonContent + "</li>");
});
});
</script>
The div "kalendi" generates a calendar, where the user can pick out some dates. Let's say, the user has chosen "2016-02-08", "2016-02-09" and "2016-02-10". The <ul class="lista"> looks like this:
<ul class="lista">
<li>2016-02-08</li>
<li>2016-02-09</li>
<li>2016-02-10</li>
</ul>
I want that, when the user presses the submit-button, that the input of <%= f.input :date%> is an array of the chosen dates. What do I need to do? Thanks in advance!
Edit: I heard, that it isn't easy to pass an array from the simple_form gem to the controller. Let's change my question a bit: What do I need to do, so the controller gets a string like this: "2016-02-08, 2016-02-09, 2016-02-10"?
Edit 2, trying to follow the advice of Albert Paul:
I added a hidden field like this:
<%= simple_form_for([#event, #dateevent]) do |f| %>
<%= f.input :date, :as => :hidden, :input_html => { :value => ".alist" } %>
<%= f.button :submit %>
<% end %>
And just for testing, I created a div called alist:
<div class="alist">abcdefghijklmnopqrstuvwxxxxz</div>
At the moment, the value of date is ".alist". What do I need to type in XXX { :value => "XXX" }, to get the content of the div? I tried something like this:$(".alist").val(), but it didn't work. Thanks in advance!
Edit3: Nevermind, I found a solution.
Rails would only pickup input tags as params, but we can do a hack and get those elements by using Javascript. Add a hidden field to your form, and add a click event to your submit button, when user submit your page use jquery to copy contents of <li></li> to this hidden field, so when it gets submitted you'll get your values inside your hidden field.
hidden_field(:signup, :pass_confirm)
http://apidock.com/rails/ActionView/Helpers/FormHelper/hidden_field
Use jquery text() to get contents of <li>
http://api.jquery.com/text/
Not the preferred way to do this, I recommend using rails checkbox tag.

Rendering a partial to an edit form inside a popover in rails 4

Hi guys I really need help here.
I'm making a todo app and displaying each task through an iteration. Next to each task I have a pencil glyphicon.
When I click on it, I want there to be a popover containing an edit form and edit the task on the spot. I'm having a ton of troubling rendering that form.
***** UPDATE *****
Clark helped me get the popover to work. But The form inside the popover is acting like a link instead of a form so I can't type in the text area.
This is my index.html.erb
<div id='user_tasks'>
<% #tasks.each do |task| %>
<ul>
<li>
<%= task.description %>
<%= link_to edit_task_path(task), :rel => 'popover', method: 'get', remote: 'true' do %>
<span class = 'edit_task_<%=task.id%> glyphicon glyphicon-pencil'> </span>
<% end %>
</li>
</ul>
<% end %>
</div>
This is the edit.js.erb
$(function(){
$('.edit_task_<%=#task.id%>').popover({
html: true,
title: 'edit',
content: <%= escape_javascript render 'edit_form', task:#task %>
}).popover('show'); });
and my controllers look like this:
def index
#new_task= Task.new
#tasks= Task.all
end
def create
#new_task= Task.new(task_params)
#task.save
redirect_to :back
end
def edit
#task= Task.find(params[:id])
end
_edit_form.html.erb looks like this: This isn't the edit form that I plan to use. Its just a copy of the create task form. I plan to fix it once I get the popover working.
<%= form_for task, :html=>{:class=> 'form-inline'} do |f| %>
<div class='form-group'>
<%= f.text_field :description, placeholder: 'create a task' %>
<%= button_tag(type:'submit', class:"btn btn-default btn-xs") do %>
<span class='glyphicon glyphicon-plus'></span>
<% end %>
</div>
<% end %>

Follow button using AJAX only updates first div

I have a _user.html.erb partial that I am rendering on my Users#Index action with a form embedded to allow following and unfollowing of each user. I also have accompanying create.js.erb and destroy.js.erb files in my relationships controller to handle the AJAX. Right now I have to refresh the page in order to see the changes made by clicking the "follow/unfollow" button next to a users name except the first user's record behaves correctly.
_user.html.erb
<div id ="follow_form">
<% if current_user.following?(user) %>
<%= form_for(current_user.relationships.find_by(followed_id: user.id),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-large" %>
<% end %>
<% else %>
<%= form_for(current_user.relationships.build(followed_id: user.id),
remote: true) do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>
<% end %>
create.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>")
$("#followers").html('<%= #user.followers.count %>')
destroy.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>")
$("#followers").html('<%= #user.followers.count %>')
here is a link to my users_controller.rb https://gist.github.com/anonymous/9608208 and my relationships_controller.rb https://gist.github.com/anonymous/9608284
I've tried changing the div to something dynamic like
<div id ="follow_form_<%= user.id %>">
But when I make the same change to the javascript like this
$("#follow_form_<%= user.id %>").find.html("<%= escape_javascript(render('users/unfollow')) %>")
it doesn't seem to work.
I've been trying to figure out how to pass the user.id attribute into the javascript but am falling flat.
It turns out the problem was in my _follow_form.html.erb partial.
I had to change
<div id="follow_form">
to
<div id="follow_form_<%= #user.id %>">
I thought I only needed to make the change in the _user.html.erb partial but I was wrong. My current user partial uses the same div id to contain the button in the Users#Index view
<div id ="follow_form_<%= user.id %>">

Rails showing series of objects with form_for and Ajax

I'm trying to show a list of "Interests" that users can "follow" by clicking on a button associated with the Interest's image. Upon clicking the button to follow an Interest, the Interest (and it's corresponding image) should disappear from the list.
I'm using a hide function in a create.js.erb file called upon by a Relationship controller when the follow button is clicked, but the function will only hide the first Interest in the series of Interests--NOT the Interest the user clicked on that needs to disappear. So there has to be a better way to set this up, but I cannot, for the life of me, figure it out. Here's my current setup:
My Controller
class StaticPagesController < ApplicationController
def home
#user = current_user
#city = request.location.city
#interests = Interest.all
end
The home page
<%= render #interests %>
The partial
<div id="follow_form">
<div class="four columns portfolio-item interests">
<div class="our-work">
<a class="img-overlay">
<%= image_tag interest.image_path %>
<div class="img-overlay-div">
<h4><%= interest.name %></h4>
</br>
<h5>Placeholder
</br>
<%= interest.desc %></h5>
<%= form_for(current_user.relationships.build(followed_id:
interest.id), remote: true) do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<%= f.submit "I'm interested", class: "b-black" %>
<% end %>
</div>
</a>
<h3><%= interest.name %><span>features info</span></h3>
</div>
</div>
</div>
And the create.js.erb that's called upon by a Relationships controller when you click the button:
$("#follow_form").hide();
UPDATE
Here is the Relationships controller for additional clarification
def create
#interest = Interest.find(params[:relationship][:followed_id])
current_user.follow!(#interest)
respond_to do |format|
format.html { redirect_to(root_url) }
format.js
end
end
You need to provide something to differentiate the different "follow_forms" that you have on the same page. Otherwise, jQuery will just select the first element and only remove that one.
One idea of how to do this would be to append the "interest.id" to the end of the follow_form id
Update your partial to be like this (assuming your partial is called and located in /app/views/interests/_follow_form.html.erb:
<div id="follow_form<%="#{interest.id} %>">
<div class="four columns portfolio-item interests">
<div class="our-work">
<a class="img-overlay">
<%= image_tag interest.image_path %>
<div class="img-overlay-div">
<h4><%= interest.name %></h4>
</br>
<h5>Placeholder
</br>
<%= interest.desc %></h5>
<%= form_for(current_user.relationships.build(followed_id:
interest.id), remote: true) do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<%= f.submit "I'm interested", class: "b-black" %>
<% end %>
</div>
</a>
<h3><%= interest.name %><span>features info</span></h3>
</div>
</div>
</div>
This way each follow_form will have a unique ID attached to it. Then you can loop through your interests and call a partial on each one like this:
home page:
<% #interests.each do |interest| %>
<%= render 'interests/follow_form', :interest => interest %>
<% end %>
create.js.erb
$("#follow_form_<%= "#{#interest.id}" %>").hide())
Your controller action can stay the same.

Using link_to_function with anchor

I have view form like this:
<% #company.projects.each do |project| %>
<%= link_to_function project.title, "toggle_information_for('#{project.id}')" %>
<br />
<div id="information_for_<%= project.id %>">
<p><%= project.information %></p>
<br/>
</div>
<% end %>
And I have this jQuery function:
function toggle_information_for(project){
$("#information_for_"+project).toggle();
}
How can I make link_to like anchor?
For example:
If I click to project.title, then opening information about project by toggle_information_for function and url changed to /#project_id. How can I make it?
I'm not sure that I understand your question, but you're looking to call the toggle_information_for JS function, you need to write your link_to like this:
<%= link_to_function project.title, "javascript:toggle_information_for('#{project.id}')" %>
If you're looking to add the project ID to your URL, try:
function toggle_information_for(project){
$('#information_for_' + project).toggle();
location.hash = project;
}
Hopefully that helps. And while this works, I'd recommend getting rid of the direct JS call in the href of the link and add an event handler directly in your JS by writing your link_to like this:
<%= link_to_function project.title, "#information_for_#{project.id}" %>
And writing your JavaScript like this:
function toggle_information_for(e){
$(e.target.href).toggle();
location.hash = project;
}
$('#wrapper_div').delegate('click', 'a', toggle_information_for);
I would advise adding a class and then separating the jQuery logic from the html.
<% #company.projects.each do |project| %>
<div class="info_for" id="info_for_<%= project.id %>">
<%=project.title%>
<br />
<div>
<p><%= project.information %></p>
<br/>
</div>
</div>
<% end %>
And then some jQuery
$('.info_for').click(function(){
$('div',this).toggle();
});

Categories