Call jQuery function from Rails link_to - javascript

I have a ruby loop that creates a list of comments..
I wonder if I can attach jQuery function to Rails link_to helper in this case?
<% #video.phrases.each do |phrase| %>
<div class = "span4" id ="comment" ><%= phrase.content %></div><a id ="ff" ><%= image_tag("ff.png", :size=> "32x32" )%></a>
<% end %>
I am hoping for something like
<% #video.phrases.each do |phrase| %>
<div class = "span4" id ="comment" ><%= phrase.content %></div><%= link_to (image_tag("ff.png", :size=> "32x32" ), html => {<script>$("#video_div").html('CONTENTS OF HTML');</script>} :remote => true %>
<% end %>
I know it won't work, but I wonder is there an easy way to achieve this kind of functionality?
Thanks!

You can do this two ways.
The first is the add an html attribute on the link_to:
<% #video.phrases.each do |phrase| %>
<div class = "span4" id ="comment" >
<%= phrase.content %>
</div>
<%= link_to (image_tag("ff.png", :size=> "32x32" ), html => {:onclick => "$('#video_div').html('CONTENTS OF HTML');"} :remote => true %>
<% end %>
The second is to separate the Javascript from Ruby:
<% #video.phrases.each do |phrase| %>
<div class = "span4" id ="comment" >
<%= phrase.content %>
</div>
<%= link_to (image_tag("ff.png", :size=> "32x32" ) :remote => true %>
<% end %>
<script type="text/javascript">
$('a').click(function(){
$("#video_div").html('CONTENTS OF HTML');
);
</script>
If you want the contents of the link tag, substitute 'CONTENTS OF HTML' for $(this).html()

Also I actually found out about Rails link_to_function helper and was able to achieve the desired behavior with:
<% #video.phrases.each do |phrase| %>
<div class = "span4" id ="comment" ><%= phrase.content %></div><a id ="ff">
<%= link_to_function image_tag("ff.png", :size=> "32x32" ), "use_comment('#{phrase.comment}')"%>
</a>

You might want to use event delegation, since it seems like you'll be creating a large number of comments.
So, borrowing from grant something like:
<% #video.phrases.each do |phrase| %>
<div class = "span4" id ="comment" >
<%= phrase.content %>
</div>
<%= link_to (image_tag("ff.png", :size=> "32x32" ) :remote => true %>
<% end %>
<script type="text/javascript">
$("#comment-wrapper-name-here").on("click", "a", function() {
$("#video_div").html('CONTENTS OF HTML');
);
</script>

Related

Appending a form in jQuery

Im trying to append a form_for to a div with no luck, I've been through everything in the javascript console inside the div that holds the form but can't seem to find the contents to target. Please let me know if this is hard to understand and i'll try to explain myself better. I have also tried
$('.admin-right-content').innerHTML = "<%= render 'products/add_products' %>"
$(".admin-right-content").append("<%= escape_javascript(render(:partial => #add_products) %>");
$(".admin-right-content").append("<%= escape_javascript(render(:partial => add_products) %>");
$(".admin-right-content").append("<%= escape_javascript(render add_products %>");
$('.admin-right-content').append($('.add-products-form'))
The list goes on and on.
I'm a newbie to Rails, so apologies if this turns out to be something simple or some silly mistake on my end.
The partial containing the form is _add_products.html.erb.
Instead of printing the form out its actually appending the code to the div.
<div class="add-products-form">
<%= form_for #product do |form| %>
<%= form.label 'Product name' %>
<%= form.text_field :product_name %>
<%= form.label 'Type'%>
<%= form.text_field :type %>
<%= form.label 'Price' %>
<%= form.text_field :price %>
<%= form.label 'Description' %>
<%= form.text_area :description %>
<%= form.label 'Add photos' %>
<%= form.data_field :photos %>
<%= form.submit "Submit" %>
<% end %>
</div>
You can try this:
$('.admin-right-content').append($('.add-products-form').children().clone())

Triggering a click through Jquery on ruby code

So I'm trying to get my f.submit to be triggered when I click f.check_box. I don't know if you can use jquery to work on ruby... But basically this is a view of a to-do list with all the items on the page. When I click the checkbox to mark it off, I want it to be automatically submitted.
I thought I could assign a div tag on the f.check_box and the f.submit to trigger them... This is the first bit of JQuery I've working with.
<h1><%= #list.title %></h1>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<div>
<h2><% #list.items.each do |item| %></h2>
<%= item.content %>
<%= form_for([#list, item]) do |f| %>
<div id="target">
<%= f.check_box :complete %>
</div>
<div id="handler">
<%= f.submit %>
<% end %>
</div>
<% end %>
</div>
<script>
jQuery(document).ready(function() {
jQuery("#target").click(function() {
jQuery("#handler").click();
});
});
</script>
<% if policy(#list).update? %>
<%= link_to "Edit List", edit_list_path, class: 'btn btn-success' %>
<% end %>
<div class="col-md-4">
<% if policy(Item.new).create? %>
<%= link_to "New Item", new_list_item_path(#list), class: 'btn btn-success' %>
<% end %>
<% if policy(#list).destroy? %>
<%= link_to "Delete List", #list, method: :delete, class: 'btn btn-danger', data: { confirm: 'Are you sure you want to destroy this lovely list?'} %>
<% end %>
</div>
</div>
<%= render "items/form" %>
<!--
new_list_item_path
/lists/5/items/new
-->
div does not fire onclick event you need to set onchange method of checkbox which will submit the form.
Here is a code for that.
You need to set different id for every submit-button and then you can submit that form using Jquery.
I set the onchange method of checkbox which submits that forms according to item id.
<h1><%= #list.title %></h1>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<div>
<%index=0%>
<h2><% #list.items.each do |item| %></h2>
<%= item.content %>
<%= form_for([#list, item]) do |f| %>
<%=f.check_box :complete,{:onchange=> "submit_form("+#list.items[index].id.to_s+");"}%>
<%= f.submit :id=>#list.items[index].id%>
<%index+=1%>
<% end %>
<% end %>
</div>
<% if policy(#list).update? %>
<%= link_to "Edit List", edit_list_path, class: 'btn btn-success' %>
<% end %>
<div class="col-md-4">
<% if policy(Item.new).create? %>
<%= link_to "New Item", new_list_item_path(#list), class: 'btn btn-success' %>
<% end %>
<% if policy(#list).destroy? %>
<%= link_to "Delete List", #list, method: :delete, class: 'btn btn-danger', data: { confirm: 'Are you sure you want to destroy this lovely list?'} %>
<% end %>
</div>
</div>
<%= render "items/form" %>
<script>
function submit_form(id) {
$('#'+id).click();
}
</script>
Um, try something like:
$("input[type=checked]").on("click", function() {
if( $(this).is(':checked') ) { $('form').submit() }
}
And you might want to
<%= f.check_box :complete, html: { class: "check_complete"} %>
and
<%= f.submit, ".." id: "handler"%>
And then replace replace the input[type=checked] with .check_complete and maybe use the ("#handler").click(); instead of .submit()

How can I specify which container when the elements are generated in a loop?

I am displaying a list of messages group by sender.
I'm also displaying a form after each group of messages so that I can reply to that particular sender.
<% #grouped_messages.each do |sender, messages| %>
<% messages.each do |msg| %>
<p><%= msg.content %></p>
<% end %>
<div class="reply-container", id='reply-container'>
<%= form_for #message do |f| %>
<%= f.text_field :content %>
<%= f.submit "Reply" %>
<% end %>
</div>
<%= link_to "Reply", '#', class: 'reply-link', id: 'reply-link' %>
<% end %>
I want to be able to show the form only when the 'Reply' link is clicked.
$(".reply-link").click(function(e){
e.preventDefault();
$('#reply-container').toggle();
$('#reply-link').toggle();
});
This doesn't work as there can only be one id on the page and all the reply-container's have the same id.
How can I specify which container to hide when the elements are dynamically generated in a loop?
you can try something like:
$(".reply-link").click(function(e){
e.preventDefault();
$(this).closest( '.reply-container').toggle();
$(this).toggle();
});
and you can remove ids: "reply-link" and "reply-container"
edit:
but you can make it better:
<div class="reply-container", id="reply-sender-#{sender.id}-container">
<%= form_for #message do |f| %>
<%= f.text_field :content %>
<%= f.submit "Reply" %>
<% end %>
</div>
<%= link_to "Reply", '#', class: 'reply-link', id: "reply-sender-#{sender.id}" %>
and then it could look like:
$(".reply-link").click(function(e){
e.preventDefault();
$("#" + $(this).attr("id") + "-container").toggle();
$(this).toggle();
});
$(".reply-link").click(function(e){
e.preventDefault();
$(this).siblings('.reply-container').toggle();
$(this).toggle();
});
Edit:
You should also separate groups into divs:
<% #grouped_messages.each do |sender, messages| %>
<div class='message_group'>
<% messages.each do |msg| %>
<p><%= msg.content %></p>
<% end %>
<div class="reply-container", id='reply-container'>
<%= form_for #message do |f| %>
<%= f.text_field :content %>
<%= f.submit "Reply" %>
<% end %>
</div>
<%= link_to "Reply", '#', class: 'reply-link', id: 'reply-link' %>
</div>
<% end %>

How do I apply function to just the class a jquery ajax submission was done from?

Here is the code I'm currently using:
$.ajax({
success: function(){
$('.post_container').append('test <br />');
}
});
<% sleep 1 %>
It is similar to the code I used for my single main micropost form but with this there are several comments that use the same class and so test is being applied to all post_containers rather than the one the post was just made to. "test" text will eventually be replaced with the div that holds the actual comments users post.
Normally I would use "this" but that won't work here.
HTML:
<div class="post_content">
<div class="post_container">
<div class="userNameFontStyle">
<%= link_to current_users_username.capitalize, current_users_username %> -
<div class="post_time">
<%= time_ago_in_words(m.created_at) %> ago.
</div>
</div>
<%= simple_format h(m.content) %>
</div>
<% if m.comments.any? %>
<% comments(m.id).each do |comment| %>
<div class="comment_container">
<%= link_to image_tag(default_photo_for_commenter(comment), :class => "commenter_photo"), commenter(comment.user_id).username %>
<div class="commenter_content">
<div class="userNameFontStyle">
<%= link_to commenter(comment.user_id).username.capitalize, commenter(comment.user_id).username %> - <%= simple_format h(comment.content) %>
</div>
</div>
<div class="comment_post_time">
<%= time_ago_in_words(comment.created_at) %> ago.
</div>
</div>
<% end %>
<% end %>
<% if logged_in? %>
<%= form_for #comment, :remote => true do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :micropost_id, :value => m.id %>
<%= f.text_area :content, :placeholder => 'Post a comment...', :class => "comment_box", :rows => 0, :columns => 0 %>
<div class="commentButtons">
<%= f.submit 'Post it', :class => "commentButton" %>
<div class="cancelButton">
Cancel
</div>
</div>
<% end %>
<% end %>
</div>
</div>
How would I deal with this?
Kind regards
NEW:
$(function() {
$('.post-form').submit(function(){
var $post_content = $(this).find('.post_content');
$.ajax({
url: this.attributes['action'],
data: $(this).serialize(),
success: function() {
$post_content.append('test <br />');
}
})
return false; //this will stop the form from really submitting.
});
});
This should do what you're looking for. Simply include this javascript anywhere.
OLD:
$('form').submit(function(){
$.ajax({
url: this.attributes['action'],
data: $(this).serialize(),
//the below line might need to be adapted.
var post_content = $(this).find('.post_content');
success: function() {
$(post_content).append('test <br />');
}
})
this assumes that there is only one form on the page. However, for the code to completely work, I need to know how to differentiate which .post_content is the "submitted" post_content. How do you programatically determine that? Is there a different button for each post_content? Or are there different forms around each post_content div? Whichever way it is, you'll have to include that somehow into the js code.
This is how I had to do it in the end.
.new_comment is my form id
$('.new_comment').on('ajax:success', function(){
$(this).parent('.post_content').find('.comment_container:last').after("<BR />TEST <BR />");
});
<% sleep 1 %>
The only issue now is identifying the actual comment_container for the post just made.

Prototype Toggle through Array Only Toggling Last Item

I'm a beginner and my brother has showed me some prototype. All the weeks successfully toggle the last week in the array but no other. Please let me know if I need to be more specific! Thanks!
<%= #athletic_program.program_name %>
<br>
<br>
<% array of_ids = Array.new %>
<% #program_weeks.each do |program_week| %>
<% array_of_ids.push(program_week.id) %>
<div id="week_number_<%= program_week.id %>" class="week_number">Week <%=program_week.week_number %></div>
<div id="program_week_form_<%= program_week.id %>" class="program_week_form">
<% form_for(program_week) do |f| %>
<%= f.error_messages %>
Number of Workouts <%= f.select :number_of_workouts, (1..7), {} %>
<%= f.submit 'Next' %>
<% end %>
</div>
<% end %>
<% content_for :javascript do %>
<script type="text/javascript">
function showForms(array_of_ids){
for(var i=0;i<array_of_ids.length;i++){
id = array_of_ids[i];
week_id = "week_number_" + array_of_ids[i];
$(week_id).onclick = function(event){
program_form = "program_week_form_" + id;
form_div = $(program_form);
if (form_div.style.display == 'none'){
form_div.style.display = 'block';
} else {
form_div.style.display = 'none';
}
}
}
}
showForms(<%= array_of_ids.to_json %>);
</script>
<% end %>
The following now works!
<%= #athletic_program.program_name %>
<br>
<br>
<% #program_weeks.each do |program_week| %>
<div id="week_number_<%= program_week.id %>" class="week_number" onclick="$('program_week_form_<%= program_week.id %>').toggle()">Week <%=program_week.week_number %></div>
<div id="program_week_form_<%= program_week.id %>" class="program_week_form" style="display:none;">
<% form_for(program_week) do |f| %>
<%= f.error_messages %>
Number of Workouts <%= f.select :number_of_workouts, (1..7), {} %>
<%= f.submit 'Next' %>
<% end %>
</div>
<% end %>
I added style="display:none;" to the program_week_form_ to have it hidden by default.
Are you simply trying to toggle the form when the week div is clicked? In that case you are really going about this the wrong way.
I think you can remove all your javascript and your array_of_ids and just change the week div to this if you're using Prototype:
<div id="week_number_<%= program_week.id %>" class="week_number" onclick="$('program_week_form_<%= program_week.id %>').toggle()">Week <%=program_week.week_number %></div>

Categories

Resources