I am trying to implement a contact form on my one-paged portfolio site using the mail_form gem and cannot seem to get the form to show up when using AJAX. I resorted to AJAX in place of the redirect_to approach because I do not want the site to refresh and scroll down to the anchor upon submission.
views/pages/home.html.erb:
<%= render 'contacts/new' %>
<div id="contact_form"></div>
config/routes.rb:
Rails.application.routes.draw do
root 'pages#home'
resources :contacts, only: [:new, :create]
end
models/contact.rb:
class Contact < MailForm::Base
attribute :name, validate: true
attribute :email, validate: /A([w.%+-]+)@([w-]+.)+([w]{2,})z/i
attribute :message, validate: true
attribute :nickname, captcha: true
def headers
{
subject: "Regarding Your Portfolio",
to: "email (removed for privacy)",
from: %("#{name}" <#{email}>)
}
end
end
controllers/contacts_controller.rb:
class ContactsController < ApplicationController
before_action :contact_params, only: [:new, :create]
def new
@contact = Contact.new
end
def create
@contact = Contact.new(params[:contact])
@contact.request = request
if @contact.deliver
respond_to do |format|
# format.html {redirect_to root_path(anchor: "contact"), notice: 'Thank you for your message! I will get back to you shortly.'}
format.html {flash.now[:notice] = 'Thank you for your message! I will get back to you shortly.'}
format.js {render partial: 'contacts/new'}
end
else
respond_to do |format|
format.html {flash.now[:alert] = 'Your message could not be sent. Please try again.'}
format.js {}
end
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :message, :nickname, :captcha)
end
end
controllers/pages_controller:
class PagesController < ApplicationController
def home
@contact = Contact.new
end
end
contacts/_new.js.erb:
document.querySelector('#contact_form').innerHTML = '<%= j render 'new', locals: {contact: @contact} %>'
contacts/_new.html.erb:
<div class="row">
<div class="mb-md-0 mb-5">
<%= form_for @contact, id: 'contact_form', remote: true do |f| %>
<div class="row">
<div class="col-2"></div>
<div class="col-md-4">
<div class="md-form mb-0">
<%= f.text_field :name, required: true, class: 'form-control', placeholder: "Name" %>
</div>
</div>
<div class="col-md-4">
<div class="md-form mb-0">
<%= f.text_field :email, required: true, class: 'form-control', placeholder: "Email" %>
</div>
</div>
</div>
<div class="row">
<div class="col-2"></div>
<div class="col-md-8">
<div class="md-form mt-4">
<%= f.text_area :message, rows: 8, required: true, class: 'form-control md-textarea', placeholder: "Message"%>
</div>
</div>
</div>
<div class= "hidden d-none">
<%= f.text_field :nickname %>
</div>
<div class="text-center text-md-left">
<%= f.submit 'Send Message', class: 'btn btn-outline-secondary btn-sm col-3 mt-4 mx-auto' %>
</div>
<% end %>
</div>
</div>
The form works, but I would love to figure out why AJAX isn’t working for it. I have searched for many hours and have also copied code from a previous application of mine that uses AJAX for a form to no avail. I want to be able to have the same effect as redirect_to root_path without having to reload the page and auto-scroll to the anchor. I have also tried copying the create method from the contacts_controller to the pages_controller with no success either. Any tips would be greatly appreciated!