How to create jQuery function for replying nested commens in Rails - javascript

How to create//change my jQuery function in create.js.erb file for creating nested comments like in the sreenshot. While creation comment using Js from create.js.erb helper method doesn't call? How to fix that?
Comments_helper.rb
module CommentsHelper
def comments_tree_for(comments)
comments.map do |comment, nested_comments|
render(comment) +
(nested_comments.size > 0 ? content_tag(:div, comments_tree_for(nested_comments), class: "replies") : nil)
end.join.html_safe
end
end
Index.html.erb
<div class="jumbotron">
<div class="container">
<h1>Join the discussion</h1>
<p>Click the button below to start a new thread:</p>
<p>
<%= link_to 'Add new topic', new_comment_path, class: 'btn btn-primary btn-lg' %>
</p>
</div>
<%= comments_tree_for #comments %>
</div>
_commnet.html.erb
<div id="comment-cont_<%= comment.id %>" class="well">
<h2><%= comment.title %></h2>
<p class="text-muted"><%= comment.root? ? "Started by" : "Replied by" %> <strong>Alex Petrov </strong> on
<%= l(comment.created_at, format: '%B, %d %Y %H:%M:%S') %></p>
<% from_reply_form ||= nil %>
<% unless from_reply_form %>
<% if comment.leaf? %>
<small class="text-muted">There are no replies yet - be the first one to reply!</small>
<% end %>
<p><div id="reply-comment_<%= comment.id%>"><%= link_to 'reply', new_comment_path(comment.id), remote: true %></p></div>
<% end %>
</div>
create.js.erb
$('#reply-comment_<%= #comment.parent_id %>').hide();
$("#comment-cont_<%= #comment.id %>").prepend('<%= j render #comment %>');

Related

Replacing text with Jquery works with class but not id

So for the view page I've tried <div id= <%= dom_id(Video.find(x.id)) %>> <%= x.get_upvotes.size %> </div>
For the upvote.js.erb page I've tried Rails.$('#<%=dom_id(Video.find(#video.id))%>').innerHTML = ("<%= j (render partial: 'book', locals: { book: #video }) %>")
On the JS page console.log('#<%=dom_id(Video.find(#video.id))%>')
gives me an output of #video_12
And on the view page <% puts dom_id(Video.find(x.id)) %> gives me an output of video_12
So I'm not sure where I'm going wrong. Any help is much appreciated.
Routes
resources :videos do#, only: [:index, :show] do
member do
put "upvote", to: "videos#upvote"
put "downvote", to: "videos#downvote"
end
end
_book.html.erb
<p> Title: <%= book.get_upvotes.size %> </p>
upvote.js.erb
Rails.$('.random-book')[1].innerHTML = ("<%= j (render partial: 'book', locals: { book: #video }) %>")
console.log('#<%=dom_id(Video.find(#video.id))%>')
console.log(Rails.$('.random-book')[0])
def upvote
def upvote
#video = Video.find(params[:id])
#ip = request.remote_ip
#was_it_upvoted = Ipaddresstracker.find_by(ipaddress: #ip, videoid: #video.id)
if #was_it_upvoted
#video.downvote_by User.first
#was_it_upvoted.delete
else
Ipaddresstracker.create(:ipaddress => #ip, :videoid => #video.id)
#video.vote_by voter: User.first, :duplicate => true
end
end
_index.html.erb
<div class="container">
<% #videos.each do |x| %>
<p> <div class="child">
<video controls width="310" height="230" src="<%= x.file %>"></video>
<p> <%= x.title %> </p>
<div>
<%= link_to upvote_video_path(x), method: :put, remote: :true, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-up"></span>
Upvote
<div class="random-book" id= <%= dom_id(Video.find(x.id)) %> > <%= x.get_upvotes.size %> </div>
<% end %>
<div>
<br><br>
<% if user_signed_in? %>
<p> Contributor: <%= x.contributor %> </p>
<p> Email: <%= x.email %> </p>
<p> Phone: <%= x.phone %> </p>
<p> <%= link_to 'Destroy', x, method: :delete, data: { confirm: 'Are you sure?' } %> </p>
<% end %>
</div>
</div>
</div> </p>
<% end %>
</div>
i think you need to add quotes
instead of
<div class="random-book" id= <%= dom_id(Video.find(x.id)) %> ></div>
do:
<div class="random-book" id="<%= dom_id(Video.find(x.id)) %>" ></div>

How to use Ajax to show first and only one comment as soon as it is created

At present my application is able to append comments to microposts that already have comments. Below is _micropost.html.erb (simplified):
<li id="micropost-<%= micropost.id %>">
<span class="content">
<%= micropost.content %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
~ <%= link_to "Comment", "#", class: "comment-link", remote: true %>
<% if micropost.comments.any? %>
~ <%= link_to "Show/hide comments", "#", class: "comments-link", remote: true %>
<% end %>
</span>
<% if logged_in? && (current_user == micropost.user || current_user.friend?(micropost.user)) %>
<div class="comment-section">
<%= form_for(current_user.comments.build, remote: true) do |f| %>
<%= f.hidden_field :micropost_id, value: micropost.id %>
<%= f.text_area :content, rows: "1", class: "comment_area" %>
<%= f.submit "Comment", class: "btn btn-primary btn-sm" %>
<% end %>
</div>
<% end %>
<div class="comments-section">
<% if micropost.comments.any? %>
<ol id="comments_micropost-<%= micropost.id %>">
<% micropost.comments.each do |comment| %>
<%= render comment %>
<% end %>
</ol>
<% end %>
</div>
</li>
create.js.erb is:
var comments = $('ol#comments_micropost-<%= #micropost.id %>');
comments.append('<%= escape_javascript(render partial: #comment) %>');
As it is conceived, create.js.erb implies that the comment created is added to other comments, that is that the comment created is not the first one. In this case, var comments is not null and the last line of code append the comment to the list of the other comments.
Also, in case micropost.comments is not nil, the user can use the "Show/hide comments" link to toggle the order list with id="comments_micropost-<%= micropost.id %>"
The problem with this configuration is that in case a user add to any micropost the first comment (that is the user writes his comment when micropost.comments == 0) there is no chance to see the result without refreshing the page.
So I am asking: how can I edit create.js.erb so that the user can see straight away the result of posting the first comment and that the "Show/hide comments" link be added to the page?
I tried the following code but it does not work:
if (comments !== null) {
comments.append('<%= escape_javascript(render partial: #comment) %>');
} else {
$('#micropost-<%= #micropost.id %>').find('.comments-section').append("<ol id='comments_micropost-<%= #micropost.id %>'><%= escape_javascript(render partial: #comment) %></ol>");
$('#micropost-<%= #micropost.id %>').find('.timestamp').append(" ~ <%= link_to 'Show/hide comments', '#', class: 'comments-link', remote: true %>");
};
<li id="micropost-<%= micropost.id %>">
<span class="content">
<%= micropost.content %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
~ <%= link_to "Comment", "#", class: "comment-link", remote: true %>
<% if micropost.comments.any? %>
~ <%= link_to "Show/hide comments", "#", class: "comments-link", remote: true %>
<% end %>
</span>
<% if logged_in? && (current_user == micropost.user || current_user.friend?(micropost.user)) %>
<div class="comment-section">
<%= form_for(current_user.comments.build, remote: true) do |f| %>
<%= f.hidden_field :micropost_id, value: micropost.id %>
<%= f.text_area :content, rows: "1", class: "comment_area" %>
<%= f.submit "Comment", class: "btn btn-primary btn-sm" %>
<% end %>
</div>
<% end %>
<div class="comments-section">
<%= render partial: comments, micropost: micropost %>
</div>
</li>
And in _comments.html.erb
<% if micropost.comments.any? %>
<ol id="comments_micropost-<%= micropost.id %>">
<% micropost.comments.each do |comment| %>
<%= render comment %>
<% end %>
</ol>
<% end %>
And in create.js.erb
var comments = $('ol#comments_micropost-<%= #micropost.id %>');
if (comments == undefined) {
$('div#comments-section').html('<%= escape_javascript(render partial: comments, micropost: #micropost) %>');
}
else {
comments.append('<%= escape_javascript(render partial: #comment) %>');
};
I solved my issue creating as originally suggested by Minu a app/views/comments/_comments.html.erb file as follows:
<% if #micropost.comments.any? %>
<ol id="comments_micropost-<%= #micropost.id %>">
<% #micropost.comments.each do |comment| %>
<%= render comment %>
<% end %>
</ol>
<% end %>
Without changing partial _micropost.html.erb I edited create.js.erb as follows:
var comments = $('ol#comments_micropost-<%= #micropost.id %>');
if (comments.length == 0) {
$('#micropost-<%= #micropost.id %>').find('.comments-section').html("<%= escape_javascript(render partial: 'comments/comments') %>");
}
else {
comments.append('<%= escape_javascript(render partial: #comment) %>');
};
When micropost.comments.any? is false, var comments is neither null or undefined, but is considered as an empty array, as can be verified by using a web browser console. Hence the use of if (comments.length == 0). See post at Stackoverflow.

Bug, switch state of boolean field

I'm using https://gorails.com/forum/switch-state-of-boolean-field as a guide toggle a boolean value. I'm using a partial to display all the objects but only the first object toggles the boolean value. Also, the ajax is not working, I have to refresh the page to show the new boolean value.
Here is posts_controller:
def toggle_confirm
respond_to do |format|
format.html
format.js
end
#post = Post.find_by(params[:id])
#post.toggle!(:confirm)
end
Here is the views/shared/_received_feed partial:
<ol class="posts">
<% #received_feed.each do |feed| %>
<%= render feed %>
<%= link_to "#{ feed.confirm ? 'Confirmed' : 'Disabled' }", toggle_confirm_post_path(feed), method: :patch, remote: :true, class: "btn btn-xs btn-#{ feed.confirm ? 'success' : 'warning' }" %>
<% end %>
</ol>
Here is the views/toggle_confirm.js.erb:
console.log(<%= #post.confirm %>);
<% if #post.confirm == true %>
$(".post-<%= #post.id %> >
a").html('3Confirmed').removeClass('btn-warning').addClass('btn-success')
<% else %>
$(".post-<%= #post.id %> > a").html('Not
Confirmed').removeClass('btn-success').addClass('btn-warning')
<% end %>
$("#post-status-<%= #post.id %>").html("<%=
#post.confirm %>")
Here is the partial for displaying each post views/posts/_posts:
<li id="post-<%= post.id %>">
<span class="user"><%= post.sender.name %></span>
<br>
<span class="image"><%= image_tag post.sender.avatar.url(:thumb) %>
</span>
<br>
<span class="note"><%= post.note %></span>
<br>
</li>

Counter span on my like button not updating with ajax

I have followed the answers suggested on other questions on SO (this question and this question ), but for some reason I can't get my like button counter to work properly with ajax. My counter changes only after a refresh, any help is appreciated thanks!
meals_controller.rb
def upvote
#meal.upvote_from current_user
if request.xhr?
render json: { count: #meal.get_upvotes.size, id: params[:id] }
else
redirect_to meals_path
end
end
def unlike
#meal.unliked_by current_user
redirect_to meals_path
end
routes.rb
Rails.application.routes.draw do
devise_for :users
root 'home#index'
resources :meals do
member do
put "like" => "meals#upvote"
put "unlike" => "meals#unlike"
end
end
#upvote.coffee
$(document).on 'ajax:success', 'a.vote', (status,data,xhr)->
$(".votes-count[data-id=#{data.id}]").text data.count
return
#index.html.erb
<p id="notice"><%= notice %></p>
<h1>Listing Meals</h1>
<% #meals.each do |meal| %>
<%= meal.title %>
<br>
<%= meal.descriptionttext %>
<%= link_to like_meal_path(meal), class: "vote", method: :put, remote: true do %>
<button>
<span class="votes-count" data-id="<% meal.id %>"><%= meal.get_likes.size %></span>
</button>
<% end %>
<%= link_to unlike_meal_path(meal), method: :put do %>
<button type="button">
<span><%= meal.get_upvotes.size%></span>
</button>
<% end %>
<br>
<% end %>
<br>

Rails form_tag unknown format error as js format with remote: true

I'm trying to add a form to a modal and then submit the form via JS format with remote: true but the form seems to be submitted as HTML instead, causing an unknown format issue. Any help would be appreciated.
Started POST "/create_deliv_extra" for 127.0.0.1 at 2014-06-16 20:38:17 -0400
Processing by DeliveriesController#create_deliv_extra as HTML
Completed 406 Not Acceptable in 21ms
ActionController::UnknownFormat
Form:
</br>
<%= form_tag create_deliv_extra_url, remote: true, class:"form-inline mb10 mt5", id:"extra_f_#{order.id}" do %>
<%= text_field_tag :description, #extra.description, placeholder: "Description", "data-provide"=>"typeahead", autocomplete: :off, "data-source"=>"#{Extra.all.pluck(:description).uniq}", class:"span4" %>
<% if order.cod == true || current_user.role == "Billing" || current_user.role == "admin" || current_user.role == "Exec" %>
<div class="input-prepend">
<span class="add-on">Amount $</span>
<%= text_field_tag :amount, #extra.amount, placeholder: "$000.00", class:"input-xs" %>
</div>
<% end %>
<div class="input-prepend">
<span class="add-on">Quantity</span>
<%= text_field_tag :quantity, #extra.quantity.present? ? "%g" % #extra.quantity : 1, class:"input-xxs" %>
</div>
<% next_d = order.deliveries.present? ? order.deliveries.maximum(:delivery_counter) + 1 : 1 %>
<div class="input-prepend">
<span class="add-on">From</span>
<%= text_field_tag :load_start, next_d, class:"input-xxxs" %>
</div>
<div class="input-prepend">
<span class="add-on">To</span>
<%= text_field_tag :load_end, next_d, class:"input-xxxs" %>
</div>
<%= select_tag :extra_type, options_for_select(["Per Yard","Per Load","Flat Fee"], #extra.extra_type), class:"input-small" %>
<%= hidden_field_tag :order_id, order.id %>
<%= hidden_field_tag :truck_id, #id %>
<%= button_tag "Add", class:"btn btn-danger" %>
<% end %>
Controller:
def create_deliv_extra
#order = Order.find(params[:order_id])
#id = params[:truck_id]
#extra = Extra.create(amount: params[:amount], extra_type: params[:extra_type], order_id: params[:order_id], description: params[:description], quantity: params[:quantity], load_start: params[:load_start], load_end: params[:load_end])
#extras = #order.next_deliv_extras.length > 1 ? "Extras: " + #order.next_deliv_extras : "No Extras"
respond_to do |format|
format.js
end
end
I've also tried adding format: :js in the form_tag but still receive the same error.
I know the question is old, but I got the same problem and found out my application.js was not requiring jquery_ujs. I added it to my application.js file:
//=require jquery
//=require jquery_ujs
Now remote links and forms work as expected :)
I believe your problem may stem from a form_tag being with another form (form_tag, form_for, or html form). If this is the case, just find a way within the html for the first form to begin and end and then start the second form after the first ends.
<%= form_for do %>
...
<%= button_tag "#" %>
<% end %>
<%= form_tag create_deliv_extra_url, remote: true, class:"form-inline mb10 mt5", id:"extra_f_#{order.id}" do %>
...
<%= button_tag "Add", class:"btn btn-danger" %>
<% end %>

Categories

Resources