Build a Rails Form (and Skip the Gems!) – Part IV: Form Reset & Success Message

Part IV: Form Reset & Success Message

Overview
Before reading this section, I encourage you to read through the previous posts in this series in case you haven’t already.

At the end of Part III I mentioned that that only two things remain to implement into the contact form: the ability to reset and the ability to display a success message to the end user. I will incorporate this functionality in this final post of this walkthrough series.

Walkthrough

Step 1: Add A Flash Notice to the Message Controller
Open the messages_controller.rb file saved in MyAppName/app/controllers and add a flash[:notice] that contains a success message.

class MessagesController < ApplicationController
def create
@message = Message.new(message_params)
respond_to do |format|
#CREATE NULL ERROR ARRAYS
@errorName = []
@errorContent = []
if @message.save
format.js {flash[:notice] = "Thanks! We've received your message."}
else
format.js
@message.errors.any?
#PUSH ERROR MESSAGES INTO ERROR ARRAYS
if (@message.errors["email"] != nil)
@errorName.push(@message.errors["name"][0])
end
if (@message.errors["content"] != nil)
@errorContent.push(@message.errors["content"][0])
end
end
end
end
 
private
def message_params
params.require(:message).permit(:email, :content)
end
end

Step 2: Add a Success Span to the Form Partial View
Open _form.html.erb saved in MyAppName/app/views/messages and add a span with the Bootstrap .help-block class. This span will contain the success message if and when it is not null.

<%= form_for @message, :html => {:class => "form-horizontal"}, remote: true do |f| %>
<div class="form-group">
<%= f.label :email, "Email address:", class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.email_field :email, class: "form-control", :placeholder => "Email"%>
<span id="emailBlock" class="help-block"></span>
</div>
</div>
<div class="form-group">
<%= f.label :content, "Message:", class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.text_area :content, class: "form-control", rows: 5 :placeholder => "Your message"%>
<span id="contentBlock" class="help-block"></span>
</div>
</div>
<%= f.submit "Submit", class: "btn btn-primary", data: {disable_with: "Loading..."} %>
<span id="helpBlock" class="help-block"></span>
<% end %>

Step 3: The JavaScript Partial View
Open the create.js.erb partial view file saved in MyAppName/app/views/messages and add code that inserts success messages into the span added in the previous step.

//REMOVE ANY PREVIOUS NOTICES
$(".notice").remove();
$(".form-group").removeClass("has-error");
 
//DISPLAY ERROR MESSAGES
$("#emailBlock").append('<div class="notice"><%=escape_javascript(@errorEmail[0])%></div>');
$("emailBlock:contains(.)").closest(".form-group").addClass("has-error");
 
$("#contentBlock").append('<div class="notice"><%=escape_javascript(@errorContent[0])%></div>');
$("contentBlock:contains(.)").closest(".form-group").addClass("has-error");
 
//DISPLAY SUCCESS MESSAGE
$("#helpBlock").append('<div class="notice"><%=escape_javascript(flash.discard(:notice))%></div>');

Step 4: Reset the Form – Messages Controller
Open the messages_controller.rb file saved in MyAppName/app/controllers and define a variable that is equal to either 1 or 0 depending on whether the new @message instance was successfully saved.

class MessagesController < ApplicationController
def create
@message = Message.new(message_params)
respond_to do |format|
#CREATE NULL ERROR ARRAYS
@errorName = []
@errorContent = []
if @message.save
format.js {flash[:notice] = "Thanks! We've received your message."}
@resetForm = "1"
else
format.js
@message.errors.any?
#PUSH ERROR MESSAGES INTO ERROR ARRAYS
if (@message.errors["email"] != nil)
@errorName.push(@message.errors["name"][0])
end
if (@message.errors["content"] != nil)
@errorContent.push(@message.errors["content"][0])
end
@resetForm = "0"
end
end
end
 
private
def message_params
params.require(:message).permit(:email, :content)
end
end

Step 5: Reset the form: JavaScript Partial View
Open the create.js.erb partial view file saved in MyAppName/app/views/messages and add the code that resets the form based on the value of the @resetForm variable.

//REMOVE ANY PREVIOUS NOTICES
$(".notice").remove();
$(".form-group").removeClass("has-error");
 
//DISPLAY ERROR MESSAGES
$("#emailBlock").append('<div class="notice"><%=escape_javascript(@errorEmail[0])%></div>');
$("emailBlock:contains(.)").closest(".form-group").addClass("has-error");
 
$("#contentBlock").append('<div class="notice"><%=escape_javascript(@errorContent[0])%></div>');
$("contentBlock:contains(.)").closest(".form-group").addClass("has-error");
 
//DISPLAY SUCCESS MESSAGE
$("#helpBlock").append('<div class="notice"><%=escape_javascript(flash.discard(:notice))%></div>');
 
//RESET FORM IF MESSAGE SAVED
<% if @resetForm == "1" %>
$(".form-horizontal")[0].reset();
<% end %>

To protect user experience, it is important to that the form does not reset following an unsuccessful submission. Isn’t it frustrating when your whole message gets deleted just because you forgot to enter your email address? That doesn’t happen in this form!

Wrap-Up
Now that you’ve reached the end of the walkthrough, go ahead and run $rails server in your computer terminal. The form should have all of the wonderful capabilities mentioned in the walkthrough Overview. The walkthrough Overview also contains all of the final code in on place for your reference. I hope you enjoy your new database-backed Ruby on Rails contact form!

What’s Next?
Now that you know how to build a contact form that stores messages in a database on a local machine, learn about how to configure this form to store messages on the Amazon Web Services global cloud in a DynamoDB database by reading my next post.

 

Did you find this walkthrough helpful?

Do you have questions on the above?

Do you see any errors?

 

If so, please leave your thoughts in the comments below.