Rails - Render html with an ajax request in controller - javascript

I would like render format.html if param[:date] != nil and render .js if it's not nil.
My link_to :
<%= link_to place_path(place, date: params[:date]), id: "#{place.id}", remote: true, authenticity_token: true, data: { title: place.city }, target: "_blank" do %>
My controller :
class PlacesController < ApplicationController
def show
if params[:date] == nil
respond_to do |format|
format.html {
preparation_of_instance_variables_for_show_view
}
format.js { }
end
else
respond_to do |format|
format.html {
preparation_of_instance_variables_for_show_view
}
format.js {
render format: 'html' # <= where I want to render format.html
}
end
go_to_show_view
end
end
private
def preparation_of_instance_variables_for_show_view
#place = Place.find_by_id(params[:id])
if params[:date].present?
#guests = Booking.accepted.where(place: #place, date: Date.parse(params[:date])).map(&:guest)
end
end
How I can to redirect to the format.html just for this case?

You say in your question that you want to render html if its != (not equal) to nil and to render js if it's not equal to nil. You can't render both on the same condition! Either way you should wrap the respond_to around the if condition:
def show
respond_to do |format|
if params[:date] # This means if params[:date] has a value (true)
format.html {
preparation_of_instance_variables_for_show_view
}
else # If params[:date] is equal to nil
format.js {}
end # End of if params[:date]
go_to_show_view
end # End of respond_to

Related

Select 'OTHERS' option from drop down list creating text field Ruby on Rails - 4.2

_form.html.erb
<div class="form-group">
<%= f.label :description %><br>
<%= f.select(:description, options_for_select([['', ''],['METRO', 'METRO'], ['BUS', 'BUS'], ['TAXI', 'TAXI'], ['OTHERS', 'OTHERS']]), {}, {class: "form-control", id: "expense_description"}) %>
<br>
<div id="otherDesc">
<%= f.text_field :description_other, class: "form-control" %>
</div>
</div>
index.html.erb
<% #expenses.each do |expense| %>
<tr class="tr-<%= cycle('odd', 'even') %>">
<td class="col-1"><%= (expense.description_other.present? ? expense.description_other : expense.description) %></td>
</tr>
<% end %>
expenses_controller.rb
class ExpensesController < ApplicationController
before_action :set_expense, only: [:show, :edit, :update, :destroy]
# GET /expenses
# GET /expenses.json
def index
#expenses = Expense.all
end
# GET /expenses/1
# GET /expenses/1.json
def show
end
# GET /expenses/new
def new
if Expense.last.present?
#expense = Expense.last.dup
else
#expense = Expense.new
end
end
# GET /expenses/1/edit
def edit
end
# POST /expenses
# POST /expenses.json
def create
#expense = Expense.new(expense_params)
respond_to do |format|
if #expense.save
format.html { redirect_to #expense, notice: 'Expense was successfully created.' }
format.json { render :show, status: :created, location: #expense }
else
format.html { render :new }
format.json { render json: #expense.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /expenses/1
# PATCH/PUT /expenses/1.json
def update
respond_to do |format|
if #expense.update(expense_params)
format.html { redirect_to #expense, notice: 'Expense was successfully updated.' }
format.json { render :show, status: :ok, location: #expense }
else
format.html { render :edit }
format.json { render json: #expense.errors, status: :unprocessable_entity }
end
end
end
# DELETE /expenses/1
# DELETE /expenses/1.json
def destroy
#expense.destroy
respond_to do |format|
format.html { redirect_to expenses_url, notice: 'Expense was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_expense
#expense = Expense.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def expense_params
params.require(:expense).permit(:description, :description_other)
end
end
expense.js
$(document).ready(function () {
$('#expense_description').on('change',function(){
var selectedValue = $(this).val();
selectedValue == "OTHERS" ? $("#otherDesc").show() : $("#otherDesc").hide()
});
});
general.scss
#otherDesc {
display:none;
}
Everything works fine except my index page where I get two values for 'OTHERS' selected option as OTHERS + MY OWN DESCRIPTION. For example in the image it is OTHERS WHITE GLUE. But I would like to have only WHITE GLUE as the description.
Please find attached the image for your reference.
I have tried too hard but unable to get the desired result.
Any suggestions are most welcome.
Thank you in advance.
Found it - I'm kind of blind sometimes...
index.html.erb
<td class="col-1"><%= expense.description %> <%= link_to expense.description_other,{}, {:style => 'color: #CC3366'} %></td>
You've got two <%= ... %>'s in there ...
<%= expense.description %>
And then
<%= link_to expense.description_other,{}, {:style => 'color: #CC3366'} %>
Get ride of the first one when OTHER is selected, using an if conditional(the trinary operator we talked about <expression> ? <if true do this happens>: <if false this happens> The conditional would have to contain both statements inside one <%= ... %> block.
Also, you have an issue here ... should have a conditional of some sort ... probably the ||= & drop the Expense.new or the Expense.last.dup
def new
#expense = Expense.new
#expense = Expense.last.dup
end

Rails 5.1.2 Ajax remote: true not working

I would like to implement ajax to create a post, without recharging the page and not going to the show (I following a tutorial) but is not working.
in the _form.html.haml you can see remote:true in the form helper
= form_for #post,remote: true do |f|
- if #post.errors.any?
#error_explanation
%h2= "#{pluralize(#post.errors.count, "error")} prohibited this post
from being saved:"
%ul
- #post.errors.full_messages.each do |message|
%li= message
.mdl-textfield.mdl-js-textfield.full-width
= f.text_area :body, class:"mdl-textfield__input"
= f.label :body, "Comparte con la Comunidad", class:"mdl-
textfield__label"
.actions.text-right
= f.submit 'Publicar', class:"mdl-button mdl-js-button mdl-button--
raised mdl-button--colored"
however when the post is created, the application redirect to the show of the post created recently in html format, it should be stay in the form.
I don't know if the version of Rails 5.1.2 has a issue, but in Rails 4 with only typing remote: true the application stay in the form after the submit action.
post controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = current_user.posts.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:body)
end
end
also I have a show.js.erb file to render a view to see the body of the post after he is created.
show.js.erb
$('#posts').append("<%= render j #post %>")
_post.haml
%article
=post.body
Done! in the post controller is missing to respond a JS format and the show.js.erb the render method has bad syntax
1) post controller: add format.js
def create
#post = current_user.posts.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
format.js { render :show }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
format.js { }
end
end
end
2) show.js.erb: the J it should be before render
$("posts").append(<%= j render #post %>)

Restriction for post to the map display

i'm currently building a web app, and I encounters some problems.
I want the map display posts that are pushed (so push == true). For that, i'd try a lot of conditions, but it's never working. I feel I am not far from the goal, but for now, the map no reference points.
posts controller :
class PostsController < ApplicationController
before_action :authenticate_user!
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :owned_post, only: [:edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all.order("push_updated_at DESC")
if #posts.push == true
#hash = Gmaps4rails.build_markers(#posts) do |post, marker|
marker.lat post.latitude
marker.lng post.longitude
end
end
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = current_user.posts.build
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = current_user.posts.build(post_params)
respond_to do |format|
if #post.save
#post.update(push: false)
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:user_id, :title, :description, :image, :push, :push_updated_at, ingredients_attributes: [:id, :name, :_destroy])
end
def owned_post
unless current_user == #post.user
flash[:alert] = "That post doesn't belong to you!"
redirect_to root_path
end
end
end
views/posts/index :
<div class="title text-center">
<h1>Alors ? On mange quoi ?</h1>
</div>
<br>
<%= render 'map' %>
<%= render 'post' %>
& views/posts/map :
<script src="//maps.google.com/maps/api/js?v=3.18&sensor=false&client=&key=&libraries=geometry&language=&hl=&region="></script>
<script src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js"></script>
<script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/infobox/1.1.9/src/infobox_packed.js' type='text/javascript'></script> <!-- only if you need custom infoboxes -->
<div style='width: 800px;'>
<div id="map" style='width: 800px; height: 400px;'></div>
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
</script>
</div>
</div>
So if you have any suggestions about that, you're welcome !!
For this stage you should create a scope on model Post
class Post < ActiveRecord::Base
scope :push, ->{ where(push: true).order("push_updated_at DESC") }
end
and then in controller
def index
#posts = Post.push #this will fetch the post with push true and sort it
#hash = Gmaps4rails.build_markers(#posts) do |post, marker|
#rest of your code
end

Agile Web Development with Rails: Two (2) items added to depot cart instead of one (1)

So I worked through the Agile Web Development with Rails book, and had a nice functional web application running on Heroku based on the "Depot" app in the book. I was editing CSS/SASS primarily, and I did something that messed up my line_item quantity in my cart.
For the life of me I can't figure out what I've done. Now when I click "Add to cart" button on my main page, 2 items are added to my cart. Does this have something to do with my database? I'm totally flummoxed after losing a bit of my flow in photoshop/CSS-land.
So in a nutshell:
I hit the "Add to cart" button, and I get two of each item I click on.
Here is my carts controller:
class CartsController < ApplicationController
skip_before_filter :authorize, only: [:create, :update, :destroy]
# GET /carts
# GET /carts.json
def index
#carts = Cart.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #carts }
end
end
# GET /carts/1
# GET /carts/1.json
def show
begin
#cart = Cart.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error "Attempt to access invalid cart #{params[:id]}"
redirect_to store_url, notice: 'Invalid cart'
else
respond_to do |format|
format.html #show.html.erb
format.json { render json: #cart }
end
end
end
# GET /carts/new
# GET /carts/new.json
def new
#cart = Cart.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #cart }
end
end
# GET /carts/1/edit
def edit
#cart = Cart.find(params[:id])
end
# POST /carts
# POST /carts.json
def create
#cart = Cart.new(params[:cart])
respond_to do |format|
if #cart.save
format.html { redirect_to #cart, notice: 'Cart was successfully created.' }
format.json { render json: #cart, status: :created, location: #cart }
else
format.html { render action: "new" }
format.json { render json: #cart.errors, status: :unprocessable_entity }
end
end
end
# PUT /carts/1
# PUT /carts/1.json
def update
#cart = Cart.find(params[:id])
respond_to do |format|
if #cart.update_attributes(params[:cart])
format.html { redirect_to #cart, notice: 'Cart was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #cart.errors, status: :unprocessable_entity }
end
end
end
# DELETE /carts/1
# DELETE /carts/1.json
def destroy
#cart = current_cart
#cart.destroy
session[:cart_id] = nil
respond_to do |format|
format.html { redirect_to store_url }
format.json { head :no_content }
end
end
end
Here is my models/cart.rb file:
class Cart < ActiveRecord::Base
attr_accessible :title, :body, :name, :quantities_attributes, :quantities, :quantity, :product_id, :line_items
#the addition of everything in attr_accessible after :body may be unnecessary if bugs show up later on...
has_many :line_items, dependent: :destroy
def add_product(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(product_id: product_id)
end
current_item
end
def total_price
line_items.to_a.sum { |item| item.total_price }
end
end
Here is my create.js.erb file
$("#notice").hide();
if ($('#cart tr').length == 1) { $('#cart').show('blind', 1000); }
$('#cart').html("<%=j render #cart %>");
$('#current_item').css({'background-color':'#fb0f19'}).
animate({'background-color':'#08BBD1'}, 1000);
Here is my application_controller.rb:
class ApplicationController < ActionController::Base
before_filter :authorize
protect_from_forgery
private
def current_cart
Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
cart = Cart.create
session[:cart_id] = cart.id
cart
end
protected
def authorize
unless User.find_by_id(session[:user_id])
redirect_to login_url, notice: "Please log in"
end
end
end
Here is my views/carts/_cart.html.erb
<% unless cart.line_items.empty? %>
<div class="cart_title">Your Comic Cart</div>
<table>
<%= render(cart.line_items) %>
<tr class="total_line">
<td colspan="2">Total</td>
<td class="total_cell"><%= cart.total_price %> BTC</td>
</tr>
</table>
<%= button_to "Checkout", new_order_path, method: :get %>
<%= button_to 'Empty cart', cart, method: :delete,
confirm: 'Are you sure?' %>
<% end %>
line_items_controller.rb:
class LineItemsController < ApplicationController
skip_before_filter :authorize, only: :create
# GET /line_items
# GET /line_items.json
def index
#line_items = LineItem.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #line_items }
end
end
# GET /line_items/1
# GET /line_items/1.json
def show
#line_item = LineItem.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #line_item }
end
end
# GET /line_items/new
# GET /line_items/new.json
def new
#line_item = LineItem.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #line_item }
end
end
# GET /line_items/1/edit
def edit
#line_item = LineItem.find(params[:id])
end
# POST /line_items
# POST /line_items.json
def create
#cart = current_cart
product = Product.find(params[:product_id])
#line_item = #cart.add_product(product.id)
respond_to do |format|
if #line_item.save
format.html { redirect_to store_url }
format.js { #current_item = #line_item }
format.json { render json: #line_item,
status: :created, location: #line_item }
else
format.html { render action: "new" }
format.json { render json: #line_item.errors, status: :unprocessable_entity }
end
end
end
# PUT /line_items/1
# PUT /line_items/1.json
def update
#line_item = LineItem.find(params[:id])
respond_to do |format|
if #line_item.update_attributes(params[:line_item])
format.html { redirect_to #line_item, notice: 'Line item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #line_item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /line_items/1
# DELETE /line_items/1.json
def destroy
#line_item = LineItem.find(params[:id])
#line_item.destroy
respond_to do |format|
format.html { redirect_to line_items_url }
format.json { head :no_content }
end
end
end
I'm not sure if there are more files worth showing, it is late and I'm super lost, so I probably should have waited until morning to post this. Let me know if anyone else has run into this. I still have a hard time with databases, so I could be completely missing the right place to be looking. Thanks for any help, I know this misstep lacks focus in my explination.
I think the problem is in your store.js.coffee. Check and modify the code as per errata 153 from below link:
http://pragprog.com/titles/rails4/errata
i.e change $(document).on "ready page:change" to $(document).on "ready, page:change"

Rails 3: odd Actionview template error when using if elsif statement

I'm using an if elsif elsif elsif end statement and I"m getting the following error as ActionView is looking for a create.js.erb file because its the name of the method. I tried to specify the :action specifically but it isn't working. If I remove the elsifs and use just a single if end statement it renders the :action 'create_like'.. shown below:
def create
if params[:liked_id]
#post = Post.find(params[:appreciation][:liked_id])
current_user.like!(#post)
respond_to do |format|
format.html { redirect_to #post }
format.js { render :action => "create_like" }
end
end
end
## ERROR
ActionView::MissingTemplate (Missing template appreciations/create with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml, :haml], :formats=>[:js, "application/ecmascript", "application/x-ecmascript", "*/*"], :locale=>[:en, :en]} in view paths "/Users/iHal/Desktop/WORK/GP/app/views", "/Users/iHal/.rvm/gems/ruby-1.9.2-p290#rails3/bundler/gems/rails_admin-0060ad2d78ed/app/views", "/Users/iHal/.rvm/gems/ruby-1.9.2-p290#rails3/gems/client_side_validations-3.1.0/app/views", "/Users/iHal/.rvm/gems/ruby-1.9.2-p290#rails3/gems/devise-1.3.4/app/views"):
UsersController
class AppreciationsController < ApplicationController
before_filter :authenticate_user!
def create
if params[:liked_id]
#post = Post.find(params[:appreciation][:liked_id])
current_user.like!(#post)
respond_to do |format|
format.html { redirect_to #post }
format.js { render :action => "create_like" }
end
elsif params[:voted_id]
#post = Post.find(params[:appreciation][:voted_id])
current_user.vote!(#post)
respond_to do |format|
format.html { redirect_to #post }
format.js { render :action => "create_vote" }
end
elsif params[:thanked_id]
#post = Post.find(params[:appreciation][:thanked_id])
current_user.thank!(#post)
respond_to do |format|
format.html { redirect_to #post }
format.js {render :action => 'create_thank'}
end
end
end
def destroy
if params[:liked_id]
#post = Appreciation.find(params[:id]).liked
current_user.unlike!(#post)
respond_to do |format|
format.html { redirect_to #post }
format.js { render :action => "destroy_like" }
end
elsif params[:vote_id]
#post = Appreciation.find(params[:id]).voted
current_user.unvote!(#post)
respond_to do |format|
format.html { redirect_to #post }
format.js { render :action => "destroy_vote" }
end
elsif params[:thanked_id]
#post = Appreciation.find(params[:id]).thanked
current_user.unthank!(#post)
respond_to do |format|
format.html { redirect_to #post }
format.js { render :action => "destroy_thank" }
end
end
end
end
edit
Started POST "/appreciations" for 127.0.0.1 at 2011-11-24 23:57:18 -0700
Processing by AppreciationsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"T3PeKRaSJSrESFTOCQ7+4LiM4BKaWkcaQ6cXpSqK38k=", "appreciation"=>{"liked_id"=>"75"}, "commit"=>"Like"}
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
Completed in 309ms
ActionView::MissingTemplate (Missing template appreciations/create with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml, :haml], :formats=>[:js, "application/ecmascript", "application/x-ecmascript",...
Sorry, you should call return after each respond_to. Because after called if, the method process continued to the end and trying to call render default. For example:
render 'your_template' and return
Or in your case
respond_to do |format|
format.html { redirect_to #post }
format.js { render :action => "create_like" }
end and return
If you examine the parameters from your request carefully, notice that you're not passing any of params[:liked_id], params[:voted_id] or params[:thanked_id]:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"T3PeKRaSJSrESFTOCQ7+4LiM4BKaWkcaQ6cXpSqK38k=", "appreciation"=>{"liked_id"=>"75"}, "commit"=>"Like"}
You are rather passing params[:appreciation][:liked_id]. It seems you should change your conditions to:
def create
if params[:appreciation][:liked_id]
# ...
elsif params[:appreciation][:voted_id]
# ...
elsif params[:appreciation][:thanked_id]
# ...
end
end

Categories

Resources