Ajax rendering with :remote => true not working on Firefox - javascript

My controller actions: advertisment_controller.rb
class AdvertismentsController < ApplicationController
before_action :set_advertisment, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!
skip_before_filter :verify_authenticity_token
layout 'admin'
respond_to :html
# GET /advertisments
# GET /advertisments.json
def index
#advertise_tab = 'active'
if current_user.is_super_admin?
#advertisments = Advertisment.all
elsif current_user.is_admin?
#advertisments = current_user.mediums.last.advertisments
elsif current_user.is_agent?
#advertisments = Advertisment.all.collect{|ad| ad if (ad.discount_rate.present? && ad.discount_rate.discount_provider == current_user.id) }.delete_if{|x| x == nil}
elsif current_user.is_member?
#advertisments = current_user.advertisments
end
end
# GET /advertisments/new
def new
if current_user.is_agent? || current_user.is_member?
#advertise_tab = 'active'
#advertisment = Advertisment.new
load_ad_components
else
redirect_to advertisments_path, flash: {error: 'You cannot create an advertisment'}
end
end
# GET /advertisments/1/edit
def edit
#mediums = Medium.all
#discount_rates = current_user.discount_rates.where(:media_category_id => #advertisment.media_category_id)
#draft_advertisments = current_user.advertisments.where(:draft => true)
respond_to do |format|
format.js
end
end
# POST /advertisments
# POST /advertisments.json
def create
#advertisment = current_user.advertisments.new(advertisment_params)
#advertisment.save
load_ad_components
respond_to do |format|
format.js
end
end
# PATCH/PUT /advertisments/1
# PATCH/PUT /advertisments/1.json
def update
#advertisment.update(advertisment_params)
load_ad_components
respond_to do |format|
format.js
end
end
# DELETE /advertisments/1
# DELETE /advertisments/1.json
def destroy
#advertisment.destroy
flash.now[:success] = "Advertisement deleted successfully."
load_ad_components
respond_to do |format|
format.js
end
end
end
My advertisments/_form.html.erb
<%= form_for(advertisment, :multipart => true, :remote => true) do |f| %>
// form fields
// advertisment is a local parameter
<% end %>
Now, if I submit this form, it is requesting the controller create method as html instead of js.
Also, for edit, I've created the link as
<li>Edit</li>
but when I click on the edit link nothing happens. No ajax call showing in the firebug console. My application.js file contains,
//= require jquery.min.js
//= require jquery_ujs
Whats wrong here? BTW, I've tested the whole edit, create, update, destroy with ajax rendering I've mentioned above in Chrome browser, and its working fine. Does anyone have any idea whats wrong with this code in firefox?
N.B. firebug for firefox show me that both the js files (jquery.min, jquery_ujs) are loaded. I've deleted my browser cache. But still the same. :'(
Any help will be appreciated.

Related

Uncaught SyntaxError: Unexpected token < in rails

This is my first question on StackOverflow. I am new to Rails and am making a simple Rails app in which I am doing a modal popup for user login in. My code is below.
App/Controller/Sessions:
class Users::SessionsController < Devise::SessionsController
# respond_to :html, :json
# before_action :check_user_session, only: [:new]
# GET /resource/sign_in
def new
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
yield resource if block_given?
respond_to do |format|
format.js
format.html
end
end
# POST /resource/sign_in
def create
self.resource = warden.authenticate(auth_options)
if self.resource.present?
set_flash_message(:notice, :signed_in)
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
else
respond_to do |format|
format.js
end
end
end
My new.js.haml file:
$("#login-modal").html("#{escape_javascript(render 'new')}");
$("#exampleModal").modal();
I am getting this error when I click the sign in button.
change file new.js.haml to new.js.erb with following code:
$("#login-modal").html("<%= escape_javascript(render 'new') %>");
$("#exampleModal").modal();

Rails flash notice via ajax

Long story short, I have a button. On clicking it, I want an ajax request to be triggered which gets flash[:notice] and displays it in a div in$
Here is my shortened view:
<input type="button" id="search" value="display"/>
<div id="notice">
</div>
My ajax request in the view:
$("#search").submit(function(){
$.ajax({
type: "POST",
url: //url to my show action
success: function(data){
/*$("#notice").html("<%= flash[:notice] %>");
$("#content").html(data);*/
}
});
return false;
});
My controller:
def HomeController < ActionController::Base
def index
end
def show
respond_to do |format|
format.js { flash[:notice] = "" + count.to_s + " results found for " + params[:query][:search_key] + "" }
end
#render :partial => 'search'
end
end
My show.js.erb
#app/views/dashboard_home/show.js.erb
$("#notice").html("<%=j flash[:notice] %>");
$("#content").html("<%=j render partial: "search" %>");
The problem is when I click on button, the notice is displayed fine. But the same notice persists on the next clicks too. The search partial contains the table Please help!
Here is an example that I got working, thanks to Rich Peck's answer. I needed to use flash.now to make sure the flash notice didn't persist.
AJAX trigger in the view:
<%= link_to "Email report", users_path, remote: true %>
Controller:
# app/controllers/users_controller
class UsersController < ApplicationController
def index
# do some things here
respond_to do |format|
format.js { flash.now[:notice] = "Here is my flash notice" }
end
end
end
Rendered view:
# app/views/users/index.js.erb
$("#flash").html('<%= j render partial: "shared/notice_banner" %>');
where the flash notice is displayed in the layout:
# app/views/layouts/application.html.erb
<div id="flash">
<% if notice.present? %>
<%= render partial: "shared/notice_banner" %>
<% end %>
</div>
# app/views/shared/_notice_banner.html.erb
<div data-alert class="alert-box">
<%= notice %>
×
</div>
Sessions
the same notice persists on the next clicks too
This is caused by the flash being stored in the session variable of Rails:
The flash is a special part of the session which is cleared with each
request. This means that values stored there will only be available in
the next request, which is useful for passing error messages etc.
The problem you have is that since I don't think ajax counts as a new request (need reference for this), the data will persist into the next time you request via HTTP.
--
Fix
I would initially try this:
def show
respond_to do |format|
format.js { flash[:notice] = "my secret number "+rand(0,5)+" !" }
end
end
The main problem you have is you're processing the flash variable in your JS using the ERB preprocessor. This is an issue as it means you won't be able to use asset precompile to help it work.
After looking at this question, why not try using the after_filter callback, like this:
#app/controllers/home_controller.rb
Class Home < ActionController::Base
after_filter { flash.discard if request.xhr? }, only: :show
def show
respond_to do |format|
format.js { flash[:notice] = "my secret number "+rand(0,5)+" !" }
end
end
end
--
Update
You should include the success functionality in your show.js.erb:
#app/views/home/show.js.erb
$("#notice").html("<%= flash[:notice] %>");
This means you can remove the whole ajax call from the application.js, and replace with the remote: true for your search form:
#app/views/search/index.html.erb
<%= form_tag home_show_path, remote: true %>
The reason this works is because when you use the format.js respond block, Rails will load the [action].js.erb file in your views. Considering this only happens after the action has been completed, it's equivalent to the success function of your ajax.
By doing this, you'll be able to remove the entire ajax function from your application.js, and replace with the UJS version, as described above

Updating rails partial with a collection through jquery

I have a form which allows users to post an update. Once the users post the update I would like the list of updates to refresh. To achieve this I'm using Ajax and jQuery and using Rails. I'm running into trouble while trying to get jquery to render the post feed partial though.
Here's the jquery I'm using
$(".microposts").html("<%= j render partial: 'shared/feed_item', collection: #feed_items %>")
At the moment, the feed just refreshes and displays nothing. I believe it's due to the way I'm trying to pass the #feed_items. What's the best way to pass that variable?
Someone asked for the controller;
class MicropostsController < ApplicationController
before_action :signed_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
respond_to do |format|
format.html { redirect_to root_url }
format.js
end
else
#feed_items = []
flash[:error] = "Failed to create micropost!"
render 'static_pages/home'
end
end
def destroy
#micropost.destroy
flash[:success] = "Micropost deleted!"
redirect_to root_url
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
def correct_user
#micropost = current_user.microposts.find_by(id: params[:id])
redirect_to root_url if #micropost.nil?
end
end
#feed_items needs to be defined somewhere in the controller. The # is a special symbol in Ruby that signifies an instance variable of the current class. If you define it somewhere else, it becomes an instance variable of that class.
Rails has some special magic that makes the instance variables of the controller available in the view. If it's not an instance variable on the controller, it won't work.
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
#feed_items = #micropost.do_whatever_to_build_the_feed_items
respond_to do |format|
format.html { redirect_to root_url }
format.js
end
else
#feed_items = []
flash[:error] = "Failed to create micropost!"
render 'static_pages/home'
end
end

jQuery plugin for rails application images not loading

I'm using the jQuery plugin Raty for my ruby on rails 4.0 application and it seems to be working except the images for the stars aren't loading onto the screen.
So those images should be stars ^ When I mouseover them in the console while running web brick the following is outputted. (My scaffold is called reviews)
Started GET "/reviews/star-off.png" for 127.0.0.1 at 2014-03-28 14:15:42 -0400
Processing by ReviewsController#show as PNG
Parameters: {"id"=>"star-off"}
Review Load (1.3ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."id" = $1 LIMIT 1 [["id", "star-off"]]
Completed 404 Not Found in 2ms
ActiveRecord::RecordNotFound (Couldn't find Review with id=star-off):
app/controllers/reviews_controller.rb:67:in `set_review'
I currently have the star images in apps/assets/javascripts/images but have also tried to put them in app/assets/images and app/views/reviews but they still won't show up. Is my issue that they aren't in the correct directory (and if so, which directory should they be in) or do I need to add some code manually to my reviews controller? Thanks.
edit: So when I try to use it in my index page, I only get an error saying this, so I must have to do something to my routes.rb file?
ActionController::RoutingError (NNo route matches [GET] "/star-off.png")
edit: as requested here is routes.rb
ConcertReview::Application.routes.draw do
resources :reviews
get "review/index"
get "review/artist"
get "review/date"
get "review/venue"
get "review/genre"
get "review/comments"
root 'reviews#index'
get 'reviews/' => 'reviews#index'
end
and here's reviews_controller.rb (autogenerated from scaffold and have not modified)
class ReviewsController < ApplicationController
before_action :set_review, only: [:show, :edit, :update, :destroy]
# GET /reviews
# GET /reviews.json
def index
#reviews = Review.all
end
# GET /reviews/1
# GET /reviews/1.json
def show
end
# GET /reviews/new
def new
#review = Review.new
end
# GET /reviews/1/edit
def edit
end
# POST /reviews
# POST /reviews.json
def create
#review = Review.new(review_params)
respond_to do |format|
if #review.save
format.html { redirect_to #review, notice: 'Review was successfully created.' }
format.json { render action: 'show', status: :created, location: #review }
else
format.html { render action: 'new' }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reviews/1
# PATCH/PUT /reviews/1.json
def update
respond_to do |format|
if #review.update(review_params)
format.html { redirect_to #review, notice: 'Review was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reviews/1
# DELETE /reviews/1.json
def destroy
#review.destroy
respond_to do |format|
format.html { redirect_to reviews_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_review
#review = Review.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def review_params
params.require(:review).permit(:artist, :venue, :date, :genre, :sound, :stagePresence, :songSelection, :overallRating, :comments)
end
end
I had that very same problem on my project. The star images do belong in app/assets/images like you tried. However, you need to pass raty a path option like such:
$('div').raty({
readOnly: true,
halfScore: true,
score: 3,
path: '/assets'
});
This is working for me.
Also, if you have turbolinks on, you're going to have to tweek any $(document).ready(function () {...}); you might have. That was the problem I had right after this one.

How do I include HTML in a JS Rails response?

I have a FooController that responds to HTML and JS (AJAX) queries:
# app/controllers/foo_controller.rb:
class FooController < ApplicationController
layout 'foo'
def bar
respond_to do |format|
format.html # foo/bar.html.erb
format.js # foo/bar.js.erb
end
end
end
The templates to support it:
# app/views/layouts/foo.html.erb:
<html>...<%= yield %>...</html>
# app/views/layouts/foo.json.erb:
<%= yield %>
And an AJAX template in which I want to render a partial:
# app/views/foo/bar.js.erb:
dojo.byID('some_div').innerHTML = "<%= escape_javascript(render(:partial => 'some/partial')) %>";
If the JS template just has plain old JS in it (like alert('hi');), it uses my JS template. When I put in the render(:partial), though, it makes the whole response use the HTML template, which means it's no longer valid JS.
A possible solution is to use a function for the layout:
class FooController < ApplicationController
layout :choose_layout
...
private
def choose_layout
return nil if request.xhr?
'foo'
end
end
But my version should work! Why doesn't it?
The most recent Railscast covers this topic (using jQuery).
I'm not quite seeing where you might be going wrong, but here's a snippit from the Railscast that works just fine to render a partial:
// views/reviews/create.js.erb
$("#new_review").before('<div id="flash_notice"><%= escape_javascript(flash.delete(:notice)) %></div>');
$("#reviews_count").html("<%= pluralize(#review.product.reviews.count, 'Review') %>");
$("#reviews").append("<%= escape_javascript(render(:partial => #review)) %>");
$("#new_review")[0].reset();
Where are you storing your Javascript? Do you have an Application.js that you're keeping things in? If so, are you including "dojo" before "application" in your javascript_include_tag?
Try the following;
class FooController < ApplicationController
layout 'foo'
def bar
respond_to do |format|
format.html
format.js { render :layout => false }
end
end
end
Hope that helps.
J.K.

Categories