What's wrong with my Ruby on Rails code? - javascript

So I've been trying to add some AJAX to my home page with rjs and I get this javascript error in a popup window:
RJS error:
TypeError: Cannot call method 'getElementsByTagName' of null
Below is all of the relevant code.
Here's my code in app/views/microposts/create.rjs:
page.insert_html :bottom, :feed_items, :partial => 'shared/feed_item', :object => #micropost
page.replace_html :user_info, pluralize(current_user.microposts.count, "micropost")
page[:micropost_form].reset
page.replace_html :notice, flash[:notice]
flash.discard
Here's app/views/pages/home.rb:
<% if signed_in? %>
<table class="front" summary="For signed-in users">
<tr>
<td class="main">
<h1 class="micropost">What's happening?</h1>
<%= render 'shared/micropost_form' %>
<%= render 'shared/feed' %>
</td>
<td class="sidebar round">
<%= render 'shared/user_info' %>
<%= render 'shared/stats' %>
</td>
</tr>
</table>
<% else %>
<h1>Sample App</h1>
<p>
This is the home page for the
Ruby on Rails Tutorial
sample application.
</p>
<%= link_to "Sign up now!", signup_path, :class => "signup_button round" %>
<% end %>
Here's my feed partial app/views/shared/_feed.html.erb:
<% unless #feed_items.empty? %>
<table id="feed_items" class="microposts" summary="User microposts">
<%= render :partial => 'shared/feed_item', :collection => #feed_items %>
</table>
<%= will_paginate #feed_items %>
<% end %>
Here's my feed item partial app/views/shared/_feed_item.html.erb
<tr id = "feed_item">
<td class="gravatar">
<%= link_to gravatar_for(feed_item.user), feed_item.user %>
</td>
<td class="micropost">
<span class="user">
<%= link_to feed_item.user.name, feed_item.user %>
</span>
<span class="content"><%= feed_item.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
</span>
</td>
<% if current_user?(feed_item.user) %>
<td>
<%= link_to "delete", feed_item, :method => :delete,
:confirm => "You sure?",
:title => feed_item.content %>
</td>
<% end %>
</tr>
And lastly here is the relevant part of my microposts controller:
class MicropostsController < ApplicationController
before_filter :authenticate, :only => [:create, :destroy]
before_filter :authorized_user, :only => :destroy
def create
#micropost = current_user.microposts.build(params[:micropost])
respond_to do |format|
if #micropost.save
flash[:success] = "Micropost created!"
format.html { redirect_to root_path }
format.js
else
#feed_items = []
render 'pages/home'
end
end
end

Given that it's an RJS error, the problem would lie in create.rjs
Try commenting out page.replace_html :notice, flash[:notice] to see if that works.

getElementsByTagName fails because it cannot find the identifier you are trying to replace. Most likely you do not have any elements on the page with the id of bottom, user_info or notice. Often times I have accidentally set the div's class but not the id, etc.

Related

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>

The action 'show' could not be found for CommentsController

I'm all new, and I'm trying to create a blog using Ruby on rails on windows 8.1.
I've made most of it, but it gives me "The action 'show' could not be found for CommentsController".
I've read several places it might be a lack of a javascript, but I have no idea where to post it.
<h1><%= #post.title %> </h1>
<%= #post.text %>
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p><%= comment.text %></p>
<p><%= time_ago_in_words comment.created_at %></p>
<p><%= link_to "Delete comment", [#post, comment], :method => :delete, :confirm => "Are you sure?" %></p>
<% end %>
<%= form_for [#post, #post.comments.build] do |f| %>
<p><%= f.text_area :text, :size => '40x10' %></p>
<p><%= f.submit "Post comment" %></p>
<% end %>
<p>
<%= link_to "Tilbage", posts_path %>
|
<%= link_to "Rediger", edit_post_path(#post) %>
|
<%= link_to "Slet", #post, :method => :delete, :confirm => "Er du sikker?" %>
</p>
This is my code in question. Any help is appreciated :)
Edit: If there is other parts you need, just let me know
Edit:
CommentController
class CommentsController < ApplicationController
def create
params.permit!
#post = Post.find(params[:post_id])
#comment = #post.comments.build(params[:comment])
#comment.save
redirect_to #post
end
def destroy
#comment = Comment.find(params[:id])
#comment.destroy
redirect_to #comment.post
end
end
Routes
Rails.application.routes.draw do
get 'comments/create'
get 'comments/destroy'
resources :posts do
resources :comments
end

Rails & Zurb Modal Loads Entire Page On Edit

I'm trying to edit content from my rails app Products through a zurb foundation modal. I can add new just fine. But when trying click the edit button, it loads a modal with the whole page again. Although it loads the correct edit page, I just want an edit form. Not a whole new render of my site.
Products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
#product = Product.new
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
#product = Product.find(params[:id])
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:name, :price)
end
end
index.html.erb
<h1>Listing products</h1>
Click Me For A Modal
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= product.price %></td>
<td><%= link_to 'Show', product %></td>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td><%= link_to 'EditM', edit_product_path(product), :remote => true, class: "", "data-reveal-id" => "editModal", "data-reveal-ajax" => edit_product_path(product) %></td>
<td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Product', new_product_path, class: "button radius", "data-reveal-id" => "addModal" %>
<div id="addModal" class="reveal-modal" data-reveal>
<%= render :partial => 'form', locals: { product: #products } %>
<a class="close-reveal-modal">×</a>
</div>
<div id="editModal" class="reveal-modal" data-reveal>
<%= render :partial => 'form' %>
<a class="close-reveal-modal">×</a>
</div>
_form.html.erb
<%= form_for(#product) do |f| %>
<% if #product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% #product.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="small-3 columns">
<%= f.label :name, class: "right inline" %>
</div>
<div class="small-9 columns">
<%= f.text_field :name %>
</div>
</div>
<div class="row">
<div class="small-3 columns">
<%= f.label :price, class: "right inline", title: "Price In USD", data: { tooltip: true } %>
</div>
<div class="small-9 columns">
<%= f.text_field :price %>
</div>
</div>
<div class="row">
<div class="small-9 small-offset-3 columns">
<%= f.submit %>
</div>
</div>
<% end %>
Below is an image of how it loads after you select the EditM button.
I have updated my :edit method to the following. It appears to be working so it loads the action only, not the layout. Is this the proper way? Or should I be doing it differently?
def edit
#product = Product.find(params[:id])
render :layout => false
end
This is the modal in index.html.erb:
<div id="editModal" class="reveal-modal" data-reveal>
<a class="close-reveal-modal">×</a>
</div>

Error display on ajax form in rails not working

I'm using an inline form for users to submit data to a table (note that I'm using CSS rather than html tables to achieve this). When an error is returned by the verification in the model, I want to highlight the input field using the Bootstrap error class and put the error message below the appropriate form field. I'm using AJAX to submit the form.
I'm having problems, this is what I have so far:
Controller:
def create
#travel = Travel.new(params[:travel])
#travel[:user_id] = current_user.id
convert_date # and return
if #travel.save
flash[:notice] = "Successfully saved trip"
#travels = Travel.where("user_id = ?",current_user)
respond_to { |format| format.js }
end
end
JS view:
<% if #travel.errors.any? %>
<% #travel.errors.full_messages.each { |msg| logger.debug(msg) } %>
<% #travel.errors.messages.each do |k,v| %>
<% logger.debug("#tf_#{k}") %>
$(<%= "#tf_#{k}" %>).insertAdjacentHTML("afterbegin","<span class="control-group error"><span class="controls">");
$(<%= "#tf_#{k}" %>).insertAdjacentHTML("beforeend","</span></span>");
$(<%= "#error_#{k}" %>).val("<%= "#{k} #{v}" %>");
<% end %>
<% else %>
$(":input:not(input[type=submit])").val("");
$("#travels_list").html("<%= escape_javascript( render(:partial => "travels") ) %>");
<% end %>
form partial:
<%= form_for #travel, :remote => true, :html => {:class => "form-inline", :id => "new-travel-form"} do |f| %>
<div class="row-fluid">
<span id="tf_city"><%= f.text_field :city, :placeholder => "London, UK", :class => "span3" %></span>
<span id="tf_arrive_date"><%= f.text_field :arrive_date, :class => "span2" %> </span>
<span id="tf_leave_date"><%= f.text_field :leave_date, :class => "span2" %> </span>
<span id="tf_notes"><%= f.text_field :notes, :placeholder => "e.g. staying at the Hilton", :class => "span3" %></span>
<%= f.submit "save", :class => "btn btn-primary span1" %>
</div>
<% end %>
<div class="row-fluid error" id="error_expl">
<span id="error_city" class="help-inline span3"></span>
<span id="error_arrive_date" class="help-inline span2"></span>
<span id="error_leave_date" class="help-inline span2"></span>
<span id="error_notes" class="help-inline span3">test</span>
</div>
The logger.debug in the JS is firing, so I know that the error is getting passed to the JS, but the insertAdjacentHMTL() doesn't seem to be working.
maybe this is not going to answer your question but i hope it could help to improve your code.
First, according to your code i guess you should have some associations like this in the model User:
has_many :travels
And in your model Travel:
belongs_to :user
So, in order to improve your code you can have this in your controller:
respond_to :js, only: [:create]
def new
#travel = current_user.travels.new
end
def create
#travel = current_user.travels.new(params[:travel])
if #travel.save
flash[:notice] = "Successfully saved trip"
#travels = current_user.travels
else
# I guess you should have some code here in case any validation fail. If you dont
# have validations for the model Travel, you don't need the if statement here.
end
end
About your problem, can you clarify what is "#tf_#{k}"?

In my comment app when i refresh the page comments disappears

My comment app works ,but the only problem is whenever i refresh the page the comments disappear.In the log it shows the body is inserted in the comments table(it is saved).What am i doing wrong here?Any help will be appreciated.Thank you in advance.
View#show
<div id="comments"></div>
<%= form_for :comment,:remote => true,:url=> {:controller=>"comments",:action=>"create"},:html => { :id => 'new-comment'} do |f| %>
<%= f.text_area(:body) %>
<div class="errors"></div>
<%= f.submit "post" %>
<% end %>
Comment controller
class CommentsController < ApplicationController
respond_to :js
def create
#deal=Deal.find(1)
#comment =#deal.comments.build(params[:comment])
#comment.save
respond_with( #comment, :layout => !request.xhr? )
end
def show
#comment=Comment.all
#deal=Deal.find(1)
#comment=#deal.comments
end
end
create.js.erb
$('#comments').append("escape_javascript(#comment.body)");
I don't see where your comments are being display in your show template.
How about something like this?
<div id="comments">
<% #comments do |comment| %>
<%= comment.body %>
<% end %>
</div>
<%= form_for :comment,:remote => true,:url=> {:controller=>"comments",:action=>"create"},:html => { :id => 'new-comment'} do |f| %>
<%= f.text_area(:body) %>
<div class="errors"></div>
<%= f.submit "post" %>
<% end %>
Note, you need to set #comments in the controller or use another method of getting comments, e.g. #view = View.find(params[:id]) and <%= #view.comments.each do |comment| %>...
I guess the comment has a belongs_to relationship with the post that is not assigned.
In your form you should add
<%= f.hidden_field :post_id, #post.id %>
If you want to play by the book, post_id should be attr_protected and instead assign it manually in the comments controller
#comment = Comment.new(params[:comment])
#comment.post_id = params[:comment][:post_id]
#comment.save

Categories

Resources