Why Ajax call is responding after a page refresh in rails 4? - ruby-on-rails

Suppose I have defined my create action like this:
def create
#appointment = Appointment.find(params[:appointment_id])
#note = #appointment.notes.new(notes_params)
#note.user_id = current_user.id
respond_to do |format|
if #note.save
format.html { redirect_to appointment_path(#appointment), notice: "Saved successfully" }
format.js
else
format.html { render 'new', notice: "Try again" }
format.js
end
end
end
My create.js.erb is like this:
$("#note_field").html("<%= j render partial: 'note', locals: {note: #note} %>");
Here is my form:
<%= form_for([#appointment, #appointment.notes.build({user: current_user})], remote: true) do |f| %>
<div>
<% if #note && #note.errors.any? %>
<% #note.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<% end %>
</div>
<div class="field">
<%= f.label :Description %><br>
<%= f.text_area :description, required: true %>
</div>
<div>
<%= f.submit class: "note-button" %>
</div>
<% end %>
Here, note is partial form. How to make it work without a page refresh?

Related

AJAX not working in Rails same-page update

I am trying to build a Q&A app with Ajax on the Index.html.erb. I manage to get the form remotely loading, but when saving the records, the AJAX does not work and the user is taken to the normal show.html.erb. Apart from the Ajax not kicking off, everything works well.
My code is as below:
index.html.erb (Contain a partial for input, and a partial for results)
<div>
<h3 class="section_title"> Q&A </h3>
<hr>
<div id="qanda-form" style="display:none;"> </div>
</div>
<div id="qandas">
<%= render 'qandas/qanda' %>
</div>
_qanda.html.erb (is the partial for results)
<% #qandas.each do |my_qanda| %>
<div class="col-md-9">
<div>
Created <%= local_time(my_qanda.created_at) %>, by <%= User.find_by(id: my_qanda.user_id).full_name %>
</div>
</div>
<% end %>
_form.html.erb (is the input form - has nested form via Cocoon)
<%= simple_form_for #qanda, remote: true do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<div class="col-md-12 form-inputs">
<div class="col-md-8">
<%= f.input :title, label: 'Q&A Title:' %>
</div>
</div>
<div class="qandasquestions">
<%= f.simple_fields_for :qandasquestions do |builder| %>
<% render 'qandas/qandasquestion_fields', f: builder %>
<% end %>
<div class="links btn-group" style="min-height: 34px !important">
<%= f.button :submit, "Publish Q&A", class: "btn btn-default" %>
<%= link_to_add_association 'Add Question', f, :qandasquestions, class: 'btn btn-default', data: {association_insertion_node: '.qandasquestions', association_insertion_method: :append} %>
<%= link_to 'Back', qandas_path, class: "btn btn-default" %>
<%= f.input :company, :as => :hidden, :input_html => {:value => current_user.company} %>
</div>
</div>
<% end %>
Controller:
def index
#qandas = Qanda.all
respond_to do |format|
#qandas = Qanda.all
format.html
format.json
end
end
def create
#qanda = current_user.qandas.build(qanda_params)
respond_to do |format|
if #qanda.save!
#qandas = Qanda.all
format.html { redirect_to #qanda, notice: 'Qanda was successfully created.' }
format.json {render :layout => false}
else
format.html { render :new }
format.json { render json: #qanda.errors, status: :unprocessable_entity }
end
end
end
create.js.erb
$('#qandas').html("<%= j render partial: 'qandas/qanda' %>");
$('#qanda-form').slideUp(350);
new.js.erb
$('#qanda-form').html("<%= j render 'qandas/form' %>");
$('#qanda-form').slideDown(350);
Anybody can see why the Ajax does not kick off please? why am I redirected to the traditional SHOW page please?
Try updating your code to this and let me know if it's working?
def create
#qanda = current_user.qandas.build(qanda_params)
if #qanda.save!
#qandas = Qanda.all
else
#errors = #qanda.errors
end
end

Rails duplicates records when using ajax to submit the form

My form needs to customize before submitting to the rails. SO, I use ajax to submit the form, but every time, rails doubles records. Anyone has any idea how it happens.
my controller here:
def create
#school_current = School.find_by_id(params[:school_id])
#quiz = Quiz.new(params[:quiz])
#quiz.from_params(params)
questions = params[:quiz][:questions_attributes]
questions.each do |index, question|
#quiz.questions.build(question)
end
respond_to do |format|
if #quiz.save
format.html { render nothing: true }
else
format.html { render action: "new" }
end
end
end
def from_params(params)
self.name = params[:quiz][:name]
self.school_id = params[:school_id]
self.description = params[:quiz][:description]
end
form:
<div id="quizzes">
<%= form_for([#school_current, #quiz], :remote => true) do |f| %>
<div class="form-inputs" id="quiz_body">
<div class="form-group">
<label>Quiz Name (required)</label>
<%= f.text_field :name, class: "form-control", placeholder: "Enter quiz name here .." %>
</div>
<div class="form-group">
<label>Quiz Description (optional)</label>
<%= f.text_area :description, :rows => 10 , :cols => 10, class: "form-control", placeholder: "Enter quiz description here .." %>
</div>
</div>
<div id="question_list">
<ol>
<%= f.fields_for :questions do |builder| %>
<li class="question_field_item"><%= render "question_fields", f: builder %></li>
<% end %>
</ol>
</div>
<div class="form-actions">
<%= f.submit "save quiz", :data => {disable_with: "Saving ..."},class: "btn btn-primary text-uppercase", id: "save_quiz" %>
</div>
<% end %>
</div>
Make sure, single AJAX request is hitting the server
the following code block might be the culprit.
respond_to do |format|
if #quiz.save
format.html { render nothing: true }
else
format.html { render action: "new" }
end
end
Try extracting the saving from respond_to's block.
if #quiz.save
respond_to do |format|
format.html { render nothing: true }
end
else
respond_to do |format|
format.html { render action: "new" }
end
end
i figured out the problem. Call question.build twice in both new and create. That's why rails duplicates the record. Remove these lines of code. It will work.
questions.each do |index, question|
#quiz.questions.build(question)
end

Error is not showing using different controller

In my task show page, I have form for creating a response and the responses are displayed here as well. (Task has many responses)
views\tasks\show.html.erb
<%= simple_form_for([#task, Response.new]) do |f| %>
<%= f.input :is_comment, as: :hidden %>
<%= f.input :negotiate_pay, label: false %>
<%= f.input :comment_text, as: :text, input_html: {rows: 3}, label: false %>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<%= f.button :submit %>
</div>
</div>
</div>
<% end %>
<br>
<div id="comments">
<%= render #responses %>
</div>
controllers\tasks_controller
def show
#task = Task.find(params[:id])
#responses = #task.responses.all
end
controllers\responses_controller
def create
#task = Task.find(params[:task_id])
#response = #task.responses.create(response_params)
#response.user_id = current_user.id
#response.is_comment = params[:is_comment]
#response.save
respond_to do |format|
format.html { redirect_to #task }
format.js
end
end
It is working alright but it doesn't show the errors in the form after validation and submit. How can I show the error message in response form which is in the show page of task. I am using a simple_form btw.
Help please
EDIT:
Models:
models\response.rb
belongs_to :user
belongs_to :task
has_many :subcomments
default_scope -> { order('created_at DESC') }
#VALIDATIONS
validates :comment_text, presence: true
validates :negotiate_pay, presence: true
You need to add the code that will display the errors to your form :
<%= simple_form_for([#task, Response.new]) do |f| %>
<% if #response.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#response.errors.count, "error") %> prohibited this response from being saved:</h2>
<ul>
<% #response.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
and you also need to tweak your create action in the responsesController:
def create
#task = Task.find(params[:task_id])
#response = #task.responses.build(response_params)
#response.user_id = current_user.id
#response.is_comment = params[:is_comment]
respond_to do |format|
if #response.save
format.html { redirect_to #task, notice: "response was createad" }
format.js
else
format.html { render :show }
end
end
also make sure you are displaying the errors inside your application.html.erb :
<% if flash[:error] -%>
<p class='alert alert-danger'><%=h flash[:error] %></p>
<% end -%>
<% if flash[:notice] -%>
<p class='alert alert-success'><%=h flash[:notice] %></p>
<% end -%>

view incorrectly reloads after uniqueness validation error

After you try to submit a new guideline and you see an error message on the form (due to the guidelines correctly failing validation)...the list of #specialties does not reload correctly (ie. it just says yes/no rather than the proper list you could see before you submitted with an error). I can't work out which part is wrong here...
VIEWS _form.html.erb
<%= simple_form_for(#guideline, html: {class: "form-horizontal"}) do |f| %>
<% if #guideline.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#guideline.errors.count, "error") %> prohibited this guideline from being saved:</h2>
<ul>
<% #guideline.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.input :title, label: 'Title (e.g. Asthma for under 12 months)' %>
<%= f.input :specialty, as: :select, collection: #specialties %>
<%= f.input :hospital %>
<%= f.input :content, as: :string, label: 'Link' %>
<div class="form-actions">
<%= f.button :submit, :class => "btn btn-info btn-large" %>
</div>
<% end %>
guidelines_controller.rb
def new
#guideline = Guideline.new
#specialties = Guideline.order(:specialty).uniq.pluck(:specialty)
respond_to do |format|
format.html # new.html.erb
format.json { render json: #guideline }
end
end
def create
#guideline = current_user.guidelines.new(params[:guideline])
respond_to do |format|
if #guideline.save
format.html { redirect_to #guideline, notice: 'Guideline was successfully created.' }
format.json { render json: #guideline, status: :created, location: #guideline }
else
#specialties = Guideline.order(:specialty).uniq.pluck(:specialty)
format.html { render action: "new" }
format.json { render json: #guideline.errors, status: :unprocessable_entity }
end
end
end
this is a common error. in your create action you should declare #specialties if the validation fails since that is needed in the new template.
def create
#guideline = Guideline.new params[:guideline]
if #guideline.save
else
# you need to declare #specialties here since it is needed in the new template
# which you want to render
#specialties = Specialty.all
render :new
end
end

After submit form I want to stay in the same page and display :notice messages

All my code is working nicely, I want to render the same page :new after a user submits a form with your order. The problem is about the :notice message that I want to display Pedido enviado com sucesso. in the page after a submission but it doesn't work. My validation error messages are displayed nicely but I don't know why my success message doesn't.
Any tips?
(Sorry about my code indentation)
My pedidos_controller goes down:
class PedidosController < ApplicationController
def new
#pedido = Pedido.new
1.times do
pessoa = #pedido.build_pessoa
produto = #pedido.produtos.build
end
respond_to do |format|
format.html # new.html.erb
format.json { render json: #pedido }
end
end
def create
#pedido = Pedido.new(params[:pedido])
respond_to do |format|
if #pedido.save
PedidosMailer.delay.registro_do_pedido(#pedido)
PedidosMailer.delay.email_para_cotar_produtos(#pedido)
format.html { redirect_to action: "new", notice: 'Pedido enviado com sucesso.' }
format.json { render json: #pedido, status: :created, location: #pedido }
else
format.html { render action: "new" }
format.json { render json: #pedido.errors, status: :unprocessable_entity }
end
end
end
end
my new.html.erb view:
<p id="notice"><%= notice %></p>
<%= render 'form' %>
my _form.html.erb view:
<%= form_for(#pedido, :html => { :class => "form-contato"}) do |f| %>
<% if #pedido.errors.any? %>
<div id="error_explanation">
<h2>Ocorreram <%= pluralize(#pedido.errors.count, "erro") %></h2>
<ul>
<% #pedido.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="span4">
<h1>Dados pessoais</h1>
<%= f.fields_for :pessoa do |builder| %>
<%= render 'pessoa_fields', f: builder %>
<% end %>
</div>
<div class="span8">
<h1>Ítens</h1>
<%= f.fields_for :produtos do |builder| %>
<%= render 'produto_fields', f: builder %>
<% end %>
</div>
<div class="span10">
<%= link_to_add_fields "Adicionar mais produtos", f, :produtos %>
</div>
<%= button_tag "Enviar", class: "btn btn-red span10", name: "commit" %>
</div>
<% end %>
my _pessoa_fields.html.erb view:
<fieldset>
<%= f.text_field :nome, class: "span4", placeholder: "Nome" %>
<br />
<%= f.text_field :telefone, class: "span4", placeholder: "Telefone" %>
<br />
<%= f.text_field :email, class: "span4", placeholder: "Email" %>
</fieldset>
my _produto_fields.html.erb view:
<% #lista_de_produtos = ["Qualibom standard", "Qualibom premium", "Bomdemais standard", "Bomdemais premium"] %>
<fieldset class="campos-produtos span10">
<div class="span3">
<%= f.select :nome, options_for_select(#lista_de_produtos, :selected => f.object.nome), :prompt => 'Selecione um produto' %>
</div>
<div class="span3">
<%= f.text_field :quantidade, class: "span3", placeholder: "Quantidade" %>
</div>
</fieldset>
You need to use flash[:notice], not notice, in your view:
<% if flash[:notice] %>
<p id="notice"><%= flash[:notice] %></p>
<% end %>
When you pass a message via the notice: parameter of redirect_to, it's placed into the flash array, which is a special pseduo-session which persist for a single request:
From the ActionController::Redirecting documentation:
It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names alert and notice as well as a general purpose flash bucket.

Resources