Creating real time chat app, but whenever I post a message I have to reload the page to see my new message. The chat does not reload by itself.
_form.html.erb
<div class="well">
<%= form_for #comment, remote: true do |f| %>
<div class="form-group">
<%= f.label :body, 'Enter your comment:' %>
<%= f.text_area :body, rows: 3, class: 'form-control', required: true, maxlength: 2000 %>
<small class="label label-warning">Cannot be blank or contain more than 2000 symbols.</small>
</div>
<%= f.submit 'Post', class: 'btn btn-primary btn-lg' %>
<% end %>
</div>
_comments.html.erb
<li class="media comment">
<%= link_to image_tag(comment.user.avatar_url, alt: comment.user.name, class: "media-object"),
comment.user.profile_url, target: '_blank', class: 'pull-left' %>
<div class="media-body">
<h4 class="media-heading"><%= link_to comment.user.name, comment.user.profile_url, target: '_blank' %> says
<small class="text-muted">[at <%= comment.created_at.strftime('%-d %B %Y, %H:%M:%S') %>]</small></h4>
<p><%= comment.body %></p>
</div>
</li>
create.js.erb
publisher = client.publish('/comments', {
message: '<%= j render #comment %>'
});
publisher.callback(function() {
$('#comment_body').val('');
$('#new_comment').find("input[type='submit']").val('Submit').prop('disabled', false)
});
publisher.errback(function() {
alert('There was an error while posting your comment.');
});
git source
Edit: added comments_controller.rb
class CommentsController < ApplicationController
def new
#comment = Comment.new
#comments = Comment.order('created_at DESC')
end
def create
respond_to do |format|
if current_user
#comment = current_user.comments.build(comment_params)
if #comment.save
flash.now[:success] = 'Your comment was successfully posted!'
else
flash.now[:error] = 'Your comment cannot be saved.'
end
format.html {redirect_to root_url}
format.js
else
format.html {redirect_to root_url}
format.js {render nothing: true}
end
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
end
Related
I have a form in the Ruby on Rails app, It has four radio buttons, three of the radio buttons have default values i.e 25, 50, and 75, the fourth radio button does not have a value, however when you click it, it displays an input field for entering any number, The form only picks the value of the input field but not the radio button values. I want the form to capture values that are checked in any of the radio buttons.
here are my form details:
<div class="row__form-control">
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 25, class: "radio_button25", :onclick=>"notification()" %>
€ <%= form.label :amount, 25 %>
</div>
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 50, class: "radio_button50", :onclick=>"notification()" %>
€ <%= form.label :amount, 50 %>
</div>
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 75, class: "radio_button75", :onclick=>"notification()" %>
€ <%= form.label :amount, 75 %>
</div>
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 0, class: "radio_custom", :onclick=>"custom()" %>
<%= form.label :custom %>
</div>
</div>
Here is my controller:
before_action :set_donation, only: %i[ show edit update destroy ]
# GET /donations or /donations.json
def index
#donations = Donation.all
end
# GET /donations/1 or /donations/1.json
def show
end
# GET /donations/new
def new
#donation = Donation.new
end
# GET /donations/1/edit
def edit
end
# POST /donations or /donations.json
def create
#donation = Donation.new(donation_params)
respond_to do |format|
if #donation.save
format.html { redirect_to donation_url(#donation), notice: "Donation was successfully created." }
format.json { render :show, status: :created, location: #donation }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #donation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /donations/1 or /donations/1.json
def update
respond_to do |format|
if #donation.update(donation_params)
format.html { redirect_to donation_url(#donation), notice: "Donation was successfully updated." }
format.json { render :show, status: :ok, location: #donation }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #donation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /donations/1 or /donations/1.json
def destroy
#donation.destroy
respond_to do |format|
format.html { redirect_to donations_url, notice: "Donation was successfully destroyed." }
format.json { head :no_content }
end
end
private
def set_donation
#donation = Donation.find(params[:id])
end
def donation_params
params.require(:donation).permit(:name, :email, :amount, :project_id)
end
It worked here:
config/routes.rb
Rails.application.routes.draw do
root "donations#new"
resources :donations, only: [:new, :create]
end
app/views/donations/new.html.erb
<%= form_with model: #donation, local: true, method: :post do |form| %>
<div class="row__form-control">
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 25, class: "radio_button25", :onclick=>"notification()" %>
€ <%= form.label :amount, 25 %>
</div>
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 50, class: "radio_button50", :onclick=>"notification()" %>
€ <%= form.label :amount, 50 %>
</div>
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 75, class: "radio_button75", :onclick=>"notification()" %>
€ <%= form.label :amount, 75 %>
</div>
<div class='row__form-control_amount'>
<%= form.radio_button :amount, 0, class: "radio_custom", :onclick=>"custom()" %>
<%= form.label :custom %>
</div>
<%= form.submit "Create Donation" %>
I created 2 records with 50 and 75 euros!
I have implemented a favorites system into my rails app, which works on the individual show page for the Tracks model. This is all handled through the Favorites controller, so I am attempting to use the same js file for both index and show pages. This is what I have tried so far. It works if I only have the show page material, the javascript doesn't work at all for either if I do it this way.
favorite.js.erb
<% if current_page?(track_path(#track)) %>
$("#favorites").html("<%= escape_javascript(render('tracks/favorites')) %>");
<% else %>
$("#favorites").html("<%= escape_javascript(render('albums/favorites')) %>");
<% end %>
the partial for tracks/favorites
<% if user_signed_in? && current_user.favorited?(#track) %>
<%= link_to image_tag('icons/heart_full.svg', width: 20), track_unfavorite_path(#track), method: :post, remote: true %>
<% else %>
<%= link_to image_tag('icons/heart_empty.svg', width: 20), track_favorite_path(#track), method: :post, remote: true %>
<% end %>
the partial for albums/favorites
<% if user_signed_in? && current_user.favorited?(track) %>
<%= link_to image_tag('icons/heart_full.svg', width: 20), track_unfavorite_path(track),
method: :post, remote: true %> <%= pluralize( track.favorites.count, 'favorite' ) %>
<% else %>
<%= link_to image_tag('icons/heart_empty.svg', width: 20), track_favorite_path(track),
method: :post, remote: true %> <%= pluralize( track.favorites.count, 'favorite' ) %>
<% end %>
Passing the instance variable as the parameter works for the show page, but trying to do it for the loop results is what is confusing me.
favorites_controller.rb
class FavoritesController < ApplicationController
before_action :authenticate_user!
before_action :find_track
def favorite
#track.favorites.where(user_id: current_user.id).first_or_create
respond_to do |format|
format.html { redirect_to #track }
format.js
end
end
def unfavorite
#track.favorites.where(user_id: current_user.id).destroy_all
respond_to do |format|
format.html { redirect_to #track }
format.js
end
end
private
def find_track
#track = Track.find(params[:track_id])
end
end
The view for Track show page is simple:
<div id="favorites">
<%= render 'tracks/favorites' %>
</div>
The view for the loop on the index page:
<% #tracks.each do |track| %>
<div class="track_thumbnail">
<% if track.avatar? %>
<%= link_to image_tag(track.avatar.url), track_path(track), width: 100, title: track.title %>
<% else %>
<%= link_to image_tag(track.user.avatar.url), track_path(track), width: 100, title: track.title %>
<% end %>
<%= link_to track.user.username, user_path(track.user) %>
</div>
<div class="track_overview">
<h2><%= link_to track.title, track_path(track) %><% if track.explicit == "explicit" %> (explicit)<% end %></h2>
<p class="description"><%= truncate(track.description, length: 160) %></p>
<div class="icons_container">
<div id="favorites">
<%= render 'albums/favorites', :track => track %>
</div>
</div>
</div>
<% end %>
I am try to render my comments with ajax in my rails app...but it is not working and the comments diplay just after I redirect the page...so the comment get created successfully but the problem is rendering comments with ajax and jquery!!!!
I have this lines in my application.html.erb:
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
and this require line in my application.js:
//= require jquery
//= require jquery_ujs
here is my show.html.erb file under posts :
<div id="posts" class="transitions-enabled">
<div class="box panel panel-default">
<%= render 'post', post: #post %>
</div>
</div>
my _post partial:
<div class="panel-body">
<%= link_to image_tag(post.user.avatar.url, size: "50x50", class: "img-circle"), profile_path(post.user.user_name) %>
<ul class="posts-shows">
<li><strong><%= link_to post.user.user_name, profile_path(post.user.user_name) %></strong></li>
<li><small><%= link_to "#{time_ago_in_words(post.created_at)} ago", post_path(post), class: "time-link" %></small></li>
</ul>
<p class="disc-posts"><%= post.description %></p>
<%= link_to image_tag(post.image.url(:large), class: "img-responsive img-in" ) %><br/>
<% if post.user == current_user %>
<div><%= link_to "Edit", edit_post_path(post) %> | <%= link_to "delete", post, method: :delete, data: {confirm: "Are you sure?"} %> </div>
<% else %>
<div><%= link_to "Repost", repost_post_path(post), method: :post, data: { confirm: "Are you sure?"} if user_signed_in? %></div>
<% end %>
</div>
<div class="panel-footer">
<div class="comment-form">
<%= form_for([post, post.comments.build], remote: true) do |f| %>
<%= f.text_field :content, placeholder: 'Add a comment...', class: "form-control comment_content", id: "comment_content_#{post.id}" %>
<% end %>
</div>
<div class="comments" id= "comments_#{post.id}">
<% if post.comments.present? %>
<%= render post.comments, post: post %>
<% end %>
</div>
</div>
my _comment.html.erb in comments folder:
<% if comment.user_id.present? %>
<div id="comment">
<%= link_to image_tag(post.user.avatar.url, size: "30x30", class: "img-circle img-comments"), profile_path(comment.user.user_name) %>
<div class="user-name">
<%= link_to comment.user.user_name, profile_path(comment.user.user_name), class: "username-size" %>
</div>
<div class="comment-content">
<%= comment.content %>
</div>
</div>
<% end %>
and here is the create.js.erb under comments folder :
$('#comments_<%= #post.id %>').append("<%=j render 'comments/comment', post: #post, comment: #comment %>");
$('#comment_content_<%= #post.id %>').val('')
and my comments controller:
class CommentsController < ApplicationController
before_action :set_post
def index
#comments = #post.comment.all
end
def new
#comment = #post.comments.build(comments_params)
end
def create
#comment = #post.comments.build(comments_params)
#comment.user_id = current_user.id
if #comment.save
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
else
flash[:alert] = "Check the comment form, something went horribly wrong."
render root_path
end
end
def destroy
#comment = #post.comments.find(params[:id])
#comment.destroy
flash[:success] = "Comment deleted :("
redirect_to root_path
end
private
def comments_params
params.require(:comment).permit(:content)
end
def set_post
#post = Post.find(params[:post_id])
end
end
I don't think this line is right -
<div class="comments" id= "comments_#{post.id}">
I think you need this
<div class="comments" id= "comments_<%= post.id %>">
I'm trying to make a simple example on a new form to send the notice of success when creating a new item using ajax.
I'm reciving a response from the server with 500 internal error.
new.js.erb
$("#flash-messages").html("<%= notice %>")
new.html.erb
<h1>New Ajax</h1>
<%= form_for(#ajax, remote: true) do |f| %>
<div id="flash-messages" >
</div>
<% if #ajax.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#ajax.errors.count, "error") %> prohibited this ajax from being saved:</h2>
<ul>
<% #ajax.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
controller
def create
#ajax = Ajax.new(ajax_params)
respond_to do |format|
if #ajax.save
format.html { redirect_to #ajax, notice: 'Ajax was successfully created.' }
format.json { render :show, status: :created, location: #ajax }
format.js { redirect_to new_ajax_path, flash[:notice] = "Fudeu" }
else
format.html { render :new }
format.json { render json: #ajax.errors, status: :unprocessable_entity }
end
end
end
I have found why was bugging my code.
Just nee do remove the flash[:notice] to notice:
Now I`m looking into giving a lifetime to this flash, like 10s and it vanishs
When I have it working I post it here for other people that may strugle as me
I don't have any idea why code works on development machine, but doesn't work on production server. I am trying to create live chat between operator and user. In development machine the user's interface and operator's works fluently. I am using pusher as web-sockets. Actually every js.erb view does not work at all in production server. There is some parts of my view.
_show.html.erb:
<%= content_tag :div, id: "chat-heading", class: %w(mpreview migedit r).include?(action_name) ? 'panel-heading2' : 'panel-heading', style: "font-size:14px;" do %>
<%= t :chat_heading %>
<i class="fa fa-arrow-up" aria-hidden="true" style="float: right;"></i>
<% end %>
<div class="panel panel-primary" style="display: none" id="chat-primary" tabindex="0">
<%= content_tag :div, class: 'panel-body', id: 'messages', data: {url: "/#{params[:locale]}/chats/#{#chat.id}/messages/"} do %>
<% unless #messages.total_pages < 2 %>
<div class="row" id="show-more-aligment">
<div class="col-md-4 col-md-offset-5" style="margin-bottom: 20px;">
<%= link_to 'Show more', url_for(:controller => 'home', :action => 'index', :page => 2, :locale => params[:locale]), :remote => true, :id => 'show_more_link' %>
</div>
</div>
<% end %>
<ul class="chat" id="chat-ul">
<% #messages.reverse_each do |message| %>
<%= render partial: 'messages/message', locals: {message: message} %>
<% end %>
</ul>
</div>
<div class="panel panel-footer">
<div class="row">
<%= simple_form_for #chat.messages.build, url: "/#{params[:locale]}/chats/#{#chat.id}/messages/", :user_id => current_user, remote: true, :html => {:autocomplete => "off"} do |f| %>
<div class="col-md-10">
<%= f.input :text, required: true, as: :string, :class => 'btn-input form-control input-sm', :placeholder => "Type your message here...", :label => false %>
</div>
<div class="col-md-2">
<%= f.submit 'Send', :class => 'btn-chat btn btn-warning btn-sm form-control msg-submit' %>
</div>
<% end %>
<% end %>
</div>
</div>
render of _show.html.erb:
<% if user_signed_in? %>
<%= content_tag :div, class: %w(mpreview migedit r).include?(action_name) ? 'welcome_chat2' : 'welcome_chat' do %>
<%= render 'chats/show' %>
<% end %>
<% end %>
controller for create method:
def create
#message = #chat.messages.new(params[:message])
#message.user = current_user
respond_to do |format|
if #message.save
format.html {redirect_to #chat}
format.js { Pusher.trigger("live_chat_#{#chat.id}", 'chat', {message: #message}) }
else
format.html {render 'new'}
format.js
end
end
end
create.js.erb:
$('#message_text').val('');
index.js.erb(adding new sent message to chat div):
if ($('#chat-ul li').length == 0){
$('ul.chat').html("<%= escape_javascript(render partial: 'messages/message', locals: {message: #message}) %>");
}
else {
$('ul.chat li:last').after("<%= escape_javascript(render partial: 'messages/message', locals: {message: #message}) %>");
}
That's it if I didn't miss something. Basically this code should add new message to database and render it on form send. Actually it saves to database but do not append it to the messages div. It gives 500 internal error. And what is most important in development machine the same exact code works like a charm, but in production it does not. This must be something with server or environment config I guess. Maybe someone has some ideas? Thanks in an advance.
ERROR IS HERE