Reputation: 1356
New to rails, so please excuse the noob question. Having some trouble with capturing e-mails via AJAX.
Desired Functionality: I'm creating a landing page for my site where we capture e-mails ("Leads" = object/model). I want to capture the e-mails asynchronously, then display a thank you message to the user. If user enters an invalid e-mail, I want to ask them to input a correct e-mail.
What I've Got Working I can correctly capture the e-mail and perform validation via AJAX. If I enter an invalid e-mail then click "submit", it is not shown on /leads/index. If I enter an invalid e-mail, it is shown on /leads/index.
What I Don't Have Working I have not figured out how to get any sort of response back to the user. All I want to do is change the text of an h3 (class="results") element if the save was successful.
My Code
landing.html.erb:
<h3 class="results">Give us your e-mail and we'll send you an invite to beta when it's ready.</h3>
<%= form_for(:lead, remote: true, :url => {:controller => 'leads', :action => 'create'}, :html => {:class => 'form-inline emailForm'}) do |f| %>
<div class="form-group">
<%= f.label(:email, 'E-mail', class: 'sr-only') %>
<%= f.text_field(:email, {:id => 'submitEmail2', :class=> 'form-lg', :placeHolder => 'E-mail Address'}) %>
</div>
<%= submit_tag("Sounds Good", {:id => 'submitEmail2', :class => 'btn btn-success btn-lg'}) %>
<% end %>
leads_controller.rb
class LeadsController < ApplicationController
layout false
#respond_to :html, :js
def index
@leads = Lead.order("created_at ASC")
end
def show
end
def new
end
def create
@lead = Lead.new(lead_params) #Create a new object without form parameters
end
def edit
end
def delete
end
private
def lead_params
params.require(:lead).permit(:email)
end
end
create.js.erb
$('h3.results').html("");
//If I remove this code, it works
<% if @lead.save? %>
$("h3.results").html("Thank you! We'll let you know when it's ready."));
$('.emailForm').hide();
<% else %>
$("h3.results").html("Invalid E-mail. Please try again!"));
<% end %>
If I remove the last bit of code in create.js.erb, everything works and the text in the h3 gets removed. What is wrong with the save statement? Am I doing the save in the correct section of my code, or should it be in the controller?
All help is appreciated!
Upvotes: 1
Views: 49
Reputation: 76774
New to rails
Welcome!
I have not figured out how to get any sort of response back to the user
Ajax
responses are always sent back on completion of the request.
How you handle it is up to you.
You'll be able to see the responses by looking at the network
tab of your devloper console
in your browser. In chrome, you'll be able to right-click > Inspect Element > Network
:
You'll be able to see the request being sent when you submit your form.
it is not shown on /leads/index
The problem you have is your save
functionality.
As mentioned by cweston
, you're best saving the record in the controller action itself (this has direct access to the model):
def create
@lead = Lead.new lead_params
@lead.save
respond_to do |format|
format.js #-> app/views/leads/create.js.erb
end
end
This will allow you to use the following (new_record?
):
#app/views/leads/create.js.erb
<% message = @lead.new_record? "Invalid Email. Please try again!" : "Thank you! We'll let you know when it's ready" %>
$("h3.results").html("<%=j message %>");
<% unless @lead.new_record? %>
$('.emailForm').fadeOut(500, function(){
$(this).remove();
});
<% end %>
This should give you the ability to manage your HTML elements in the DOM.
Response
In terms of your response, the fact you're using the inbuilt server-side JS is great; I applaud that.
The other way you could handle your response would be to use client-side Ajax. You don't need to do this, as you're using the Rails UJS driver, but here's how you'd do it anyway:
#app/assets/javascripts/application.js
$(document).on("submit", "form#new_lead", function(e) {
$.ajax({
url: $(this).attr("action"),
data: $(this).serialize(),
success: function(data) {
// stuff here
},
error: function(data) {
// stuff here
}
});
});
Upvotes: 1
Reputation: 1356
Answer
I'm an idiot. The error was because of the double parenthesis at the end of my $('h3.results')
calls.
Upvotes: 0
Reputation: 11637
I believe you are getting an error on the line:
<% if @lead.save? %>
You should be performing the save in the controller:
def create
lead = Lead.new(lead_params)
@saved = lead.save
end
Note the use of save
not save?
You can then test if @lead.save
was successful in your view with @saved
:
$('h3.results').html("");
<% if @saved %>
$("h3.results").html("Thank you! We'll let you know when it's ready."));
$('.emailForm').hide();
<% else %>
$("h3.results").html("Invalid E-mail. Please try again!"));
<% end %>
Upvotes: 1