create.js.erb is called only one time after form submit - ruby-on-rails

I have a simple_form_for in my project. My goal is to alert people when their email is already in database thanks to an alert and ajax to reload the form if there is an error. When I send my form for the first time, I get the good respond from create.js.erb. But if I send the form a second time without reloading the page with the browser, my controller create method code is taken into account but not my create.js.erb code. For example, if I put an alert in the create.js.erb file, it doesn't pop the second time I send the form by clicking on the button again. Can you help me to figure why ?
pages_controller.rb
def create
#email = waiting_list_params[:email]
#waiting_user = WaitingList.new(waiting_list_params)
respond_to do |format|
if #waiting_user.save
UserMailer.welcome(#email).deliver_now
format.html { redirect_to concours_path }
format.js
else
format.html { render 'pages/concours' }
format.js { flash[:error] = #waiting_user.errors.full_messages[0] }
end
end
end
create.js.erb
function refreshForm(innerHTML) {
const newForm = document.getElementById("concours-form");
newForm.innerHTML = innerHTML;
}
<% if #waiting_user.errors.any? %>
refreshForm('<%= j render "pages/concours_form" %>');
confPopup.style.display = "none";
<% else %>
confPopup.style.display = "flex";
<% end %>
_form.html.erb
<%= simple_form_for #waiting_user, {id: 'concours-form', url: concours_path, remote: true} do |f| %>
<%= f.error_notification %>
<%= f.text_field :email,
class: "landing-form-input",
autocomplete: "off",
required: true,
pattern: '[^#]+#[^#]+\.[a-zA-Z]{2,6}',
placeholder: "Renseignez ton email ici"
%>
<i class="fa fa-envelope"></i>
<%= f.hidden_field :concours_city,
value:'',
id: 'c-choosen-city'
%>
<%= f.hidden_field :source,
value: params[:source]
%>
<%= f.button :submit,
class: "landing-form-button",
value: "Je tente ma chance !"
%>
<% end %>
routes.rb
get 'concours', to: 'pages#concours'
post 'concours', to: 'pages#create'

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 Ajaxified form doesn't render errors

I'm trying to implement a simple uniqueness validation on a Rails Ajaxified form. Unfortunately, my validation error is not printed when the validation is not accepted. Can you help me to figure why?
model.rb
class WaitingList < ApplicationRecord
validates :email, uniqueness: true
end
controller.rb
def create_concours
#email = params[:email]
#waiting_user = WaitingList.new(email: #email, source: params[:source], concours_city: params[:choosen_city])
#First Ajax of Weekendr History snif
respond_to do |format|
if #waiting_user.save
UserMailer.welcome(#email).deliver_now
format.html { redirect_to concours_path }
format.js
else
format.html
format.js
end
end
end
_form.html.erb
<%= form_tag concours_path, {id: 'concours-form', remote: true} do %>
<%= text_field_tag :email,
value = nil,
class: "landing-form-input",
autocomplete: "off",
required: true,
pattern: '[^#]+#[^#]+\.[a-zA-Z]{2,6}',
placeholder: "Renseignez ton email ici"
%>
<i class="fa fa-envelope"></i>
<%= hidden_field_tag :choosen_city, '', id: 'c-choosen-city'%>
<%= hidden_field_tag 'source', params[:source] %>
<%= button_tag :submit, class: "landing-form-button" do %>
Je tente ma chance !
<% end %>
<% end %>
create_concours.js.erb
function refreshForm(innerHTML) {
const form = document.getElementById("concours-form");
form.innerHTML = innerHTML;
}
<% if #waiting_user.errors.any? %>
refreshForm('<%= j render "form" %>');
<% end %>

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

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?

Ruby Problems Displaying Variables From New View, but Not Edit

In my app I have a quiz in a partial because I need the same (lengthy) quiz for my new and for my edit view. In the header of the application.html.erb and on my users#show page I display the results from this quiz, once it is taken, using an if/else statement. For some reason, after a user takes the quiz in the new view it is registering that the quiz has been completed (you can tell by the if/else statement) but not displaying the variables. However, using the edit view (that calls the same partial _quiz.html.erb) the variables display perfectly.
My new view calls the partial like this:
<%= render partial: "quiz", locals: { url: swing_books_path, method: :post } %>
While my edit view calls it like this:
<%= render partial: "quiz", locals: { url: edit_swing_book_path(#swing_book), method: :put } %>
The partial looks like this:
<%= form_for #swing_book do |f| %>
<div class="clearfix">
<h1 class="text-center">
<%= f.text_field :swing01, class: 'form-control input-1' %>
<%= f.text_field :swing02, class: 'form-control input-1' %>
<%= f.text_field :swing03, class: 'form-control input-1' %>
-
<%= f.text_field :swing04, class: 'form-control input-1' %>
<%= f.text_field :swing05, class: 'form-control input-1' %>
<%= f.text_field :swing06, class: 'form-control input-1' %>
-
<%= f.text_field :swing07, class: 'form-control input-1' %>
<%= f.text_field :swing08, class: 'form-control input-1' %>
<%= f.text_field :swing09, class: 'form-control input-1' %>
<%= f.text_field :swing10, class: 'form-control input-1' %>
</h1>
<div class="form-group text-center">
<%= f.submit "Submit Swing Code", class: 'btn btn-success' %>
</div>
</div>
<% end %>
However, I use these exact same details (with just the variable names changed) on another quiz that is not having the same issue. (I have three other similar quizzes all of which display perfectly from both new and edit views.)
My model looks like this:
class SwingBook < ActiveRecord::Base
before_save :set_swing_code
def set_swing_code
self.swing_code = "#{self.swing01}#{self.swing02}#{self.swing03}-#{self.swing04}#{self.swing05}#{self.swing06}-#{self.swing07}#{self.swing08}#{self.swing09}#{self.swing10}"
end
belongs_to :user
validates :user, presence: true
end
My controller looks like this:
class SwingBooksController < ApplicationController
before_action :require_sign_in
def show
#swing_book = SwingBook.find(params[:id])
end
def new
#swing_book = current_user.build_swing_book
end
def create
#swing_book = SwingBook.new
#swing_book.swing_code = params[:swing_book][:swing01]
#swing_book.swing_code = params[:swing_book][:swing02]
#swing_book.swing_code = params[:swing_book][:swing03]
#swing_book.swing_code = params[:swing_book][:swing04]
#swing_book.swing_code = params[:swing_book][:swing05]
#swing_book.swing_code = params[:swing_book][:swing06]
#swing_book.swing_code = params[:swing_book][:swing07]
#swing_book.swing_code = params[:swing_book][:swing08]
#swing_book.swing_code = params[:swing_book][:swing09]
#swing_book.swing_code = params[:swing_book][:swing10]
#swing_book.swing_code = params[:swing_book][:swing_code]
#swing_book.user = current_user
if #swing_book.save
flash[:notice] = "Your swing code was saved successfully."
redirect_to user_path(current_user)
else
flash[:alert] = "Sorry, your results failed to save."
redirect_to welcome_index_path
end
end
def edit
#swing_book = SwingBook.find(params[:id])
end
def update
#swing_book = SwingBook.find(params[:id])
#swing_book.assign_attributes(swing_book_params)
if #swing_book.save
flash[:notice] = "Results were updated successfully."
redirect_to user_path(current_user)
else
flash.now[:alert] = "There was an error saving your results. Please try again."
redirect_to welcome_index_path
end
end
private
def swing_book_params
params.require(:swing_book).permit(:swing01, :swing02, :swing03, :swing04, :swing05, :swing06, :swing07, :swing08, :swing09, :swing10, :swing_code)
end
end
Finally, here's the logic I'm using to display these variables in the application.html.erb file:
<% if current_user.swing_book != nil %>
<p>ID Code:
<%= current_user.swing_book.swing01 %>
<%= current_user.swing_book.swing02 %>
<%= current_user.swing_book.swing03 %>
-
<%= current_user.swing_book.swing04 %>
<%= current_user.swing_book.swing05 %>
<%= current_user.swing_book.swing06 %>
-
<%= current_user.swing_book.swing07 %>
<%= current_user.swing_book.swing08 %>
<%= current_user.swing_book.swing09 %>
<%= current_user.swing_book.swing10 %></p>
<% end %>
And on the user#show page:
<% if #user.swing_book == nil %>
<h3>ID Code: ???-???-????<%= %></h3>
<p><%= link_to "Get Your ID Code Now!", new_swing_book_path %></p>
<% else %>
<h3>ID Code:
<%= #user.swing_book.swing01 %>
<%= #user.swing_book.swing02 %>
<%= #user.swing_book.swing03 %>
-
<%= #user.swing_book.swing04 %>
<%= #user.swing_book.swing05 %>
<%= #user.swing_book.swing06 %>
-
<%= #user.swing_book.swing07 %>
<%= #user.swing_book.swing08 %>
<%= #user.swing_book.swing09 %>
<%= #user.swing_book.swing10 %></h3>
<p><%= link_to "Update Your Code", edit_swing_book_path(#user.swing_book) %></p>
<% end %>
I originally tried displaying just the swing_code variable (as established in the method, but it was displaying a single integer so I switched to the code seen above. Ideally, I would like to display it as just the swing_code variable, but the (somewhat repetitive) workaround I'm currently using works fine-ish if I could only get the new/edit display issue worked out.
Any ideas as to what could be going wrong? I can't find any differences between this and the other quizzes that could be causing a problem!
In your create method, you have a block of code that explicitly sets the #swing_book values. This code is setting all of the values from the form into just the swing_code member. Since the last assignment is also from the swing_code param to the swing_code member, it's hiding the mistake. Here's the code with the correct member fields assigned:
#swing_book.swing01 = params[:swing_book][:swing01]
#swing_book.swing02 = params[:swing_book][:swing02]
#swing_book.swing03 = params[:swing_book][:swing03]
#swing_book.swing04 = params[:swing_book][:swing04]
#swing_book.swing05 = params[:swing_book][:swing05]
#swing_book.swing06 = params[:swing_book][:swing06]
#swing_book.swing07 = params[:swing_book][:swing07]
#swing_book.swing08 = params[:swing_book][:swing08]
#swing_book.swing09 = params[:swing_book][:swing09]
#swing_book.swing10 = params[:swing_book][:swing10]
#swing_book.swing_code = params[:swing_book][:swing_code]
Now, while that will fix the immediate problem, you probably just want to use the same approach as the update method. Try this for your create method, instead:
def create
#swing_book = SwingBook.new
#swing_book.assign_attributes(swing_book_params)
#swing_book.user = current_user
if #swing_book.save
flash[:notice] = "Your swing code was saved successfully."
redirect_to user_path(current_user)
else
flash[:alert] = "Sorry, your results failed to save."
redirect_to welcome_index_path
end
end
However, you have an opportunity to minimize the overall code to help eliminate errors like this. Consider something like this for your controller code:
class SwingBooksController < ApplicationController
before_action :require_sign_in
def show
#swing_book = SwingBook.find(params[:id])
end
def new
#swing_book = current_user.build_swing_book
end
def edit
#swing_book = SwingBook.find(params[:id])
end
def create
#swing_book = SwingBook.new
apply_form_values
end
def update
#swing_book = SwingBook.find(params[:id])
apply_form_values
end
private
def apply_form_values
#swing_book.assign_attributes(swing_book_params)
if #swing_book.save
flash[:notice] = "Results were updated successfully."
redirect_to user_path(current_user)
else
flash.now[:alert] = "There was an error saving your results. Please try again."
redirect_to welcome_index_path
end
end
def swing_book_params
params.require(:swing_book).permit(:swing01, :swing02, :swing03, :swing04, :swing05, :swing06, :swing07, :swing08, :swing09, :swing10, :swing_code)
end
end
You can use techniques like this to make it easier to write your initial code, and make it far easier to maintain.

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

Resources