Skip to content

Commit

Permalink
Steal the feedback form from PURL
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeer committed Mar 1, 2018
1 parent a256ac4 commit 20e670d
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 43 deletions.
136 changes: 136 additions & 0 deletions app/assets/javascripts/feedback_form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
$(document).on("turbolinks:load", function(){

//Instantiates plugin for feedback form

$("#feedback-form").feedbackForm();
})


;(function ( $, window, document, undefined ) {
/*
jQuery plugin that handles some of the feedback form functionality
Usage: $(selector).feedbackForm();
No available options
This plugin :
- changes feedback form link to button
- submits an ajax request for the feedback form
- displays alert on response from feedback form
*/

var pluginName = "feedbackForm";

function Plugin( element, options ) {
this.element = element;
var $el, $form;

this.options = $.extend( {}, options) ;
this._name = pluginName;
this.init();
}

function submitListener(){
// Serialize and submit form if not on action url
$form.each(function(i, form){
if (location !== form.action){
$('#user_agent').val(navigator.userAgent);
$('#viewport').val('width:' + window.innerWidth + ' height:' + innerHeight);
$(form).on('submit', function(){
var valuesToSubmit = $(this).serialize();
$.ajax({
url: form.action,
data: valuesToSubmit,
type: 'post'
}).success(function(response){
if (isSuccess(response)){
$($el).collapse('hide');
$($form)[0].reset();
}
renderFlashMessages(response);
});
return false;
});

}
});
}

function isSuccess(response){
switch(response[0][0]){
case 'success':
return true;
default:
return false;
}
}

function renderFlashMessages(response){
$.each(response, function(i,val){
var flashHtml = "<div class='alert alert-" + val[0] + "'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;</button>" + val[1] + "</div>";

// Show the flash message
$('div.flash_messages').html(flashHtml);
});
}

function replaceLink(form, link) {
var attrs = {};
$.each(link[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.value;
});
attrs.class = 'cancel-link btn btn-link';

// Replace the cancel link with a button
link.replaceWith(function() {
return $('<button />', attrs).append($(this).contents());
});

// Cancel link should not submit form
form.find('button.cancel-link').on('click', function(e){
e.preventDefault();
});
}

Plugin.prototype = {

init: function() {
$el = $(this.element);
$form = $($el).find('form');
$cancelLink = $($el).find(".cancel-link");

// Replace "Cancel" link with link styled button
replaceLink($el, $cancelLink);

//Add listener for form submit
submitListener($el,$form);

// Preventing link from triggering navigation
$('*[data-target="#' + this.element.id +'"]').on('click', function(e){
e.preventDefault();
});

//Updates reporting from fields for current location
$('span.reporting-from-field').html(location.href);
$('input.reporting-from-field').val(location.href);

// Listen for form open and then add focus to message
$('#feedback-form').on('shown.bs.collapse', function () {
$("textarea#message").focus();
});
}
};

// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName,
new Plugin( this, options ));
}
});
};

})( jQuery, window, document );
16 changes: 16 additions & 0 deletions app/assets/stylesheets/feedback-form.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.cancel-link .btn .btn-link {
margin-left:12px;
border-bottom: none;
}

#feedback-form{
border-bottom: 3px solid $sul-toolbar-border;
}

.feedback-alert {
color: rgb(204, 0, 0);
font-size: 1.2em;
padding: 10px;
border: 1px solid rgb(204, 0, 0);
margin: 10px 0pt;
}
32 changes: 32 additions & 0 deletions app/controllers/feedback_forms_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class FeedbackFormsController < ApplicationController
def new; end

def create
if validate
FeedbackMailer.submit_feedback(params, request.remote_ip).deliver_now
flash[:success] = 'Thank you! Your feedback has been sent.'
end

respond_to do |format|
format.json do
render json: flash
end
format.html do
redirect_to params[:url]
end
end
end

protected

def validate
errors = []
errors << 'A message is required' if params[:message].blank?

if params[:email_address].present?
errors << 'You have filled in a field that makes you appear as a spammer. Please follow the directions for the individual form fields.'
end
flash[:error] = errors.join('<br/>') unless errors.empty?
flash[:error].nil?
end
end
4 changes: 4 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ def current_term
def future_terms(*args)
Terms.future_terms(*args)
end

def show_feedback_form?
Settings.email.feedback.present?
end
end
26 changes: 26 additions & 0 deletions app/mailers/feedback_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class FeedbackMailer < ActionMailer::Base
def submit_feedback(params, ip)
@name = if params[:name].present?
params[:name]
else
'No name given'
end

@email = if params[:to].present?
params[:to]
else
'No email given'
end

@message = params[:message]
@url = params[:url]
@ip = ip
@user_agent = params[:user_agent]
@viewport = params[:viewport]

mail(to: Settings.feedback.email_to,
subject: 'Feedback from PURL',
from: '[email protected]',
reply_to: Settings.feedback.email_to)
end
end
1 change: 1 addition & 0 deletions app/views/feedback_forms/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= render 'shared/feedback_forms/form' %>
10 changes: 10 additions & 0 deletions app/views/feedback_mailer/submit_feedback.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Name: <%= @name %>
Email: <%= @email %>
Comment:
<%= @message.html_safe unless @message.nil? %>

Message sent from: <%= @url %>
Host: <%= Settings.HOSTNAME %>
IP: <%= @ip %>
User agent: <%= @user_agent %>
Viewport: <%= @viewport %>
8 changes: 8 additions & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@
<header id="header">
<%= link_to(image_tag("sul.png"), "http://library.stanford.edu", :class=>"img-link") %>
<span id="links">
<%= link_to feedback_path, class: 'first', data: {toggle:"collapse", target:"#feedback-form"} do %>
Feedback
<% end if show_feedback_form? %>
<%= current_user %> <span>(close browser to logout)</span>
</span>
</header>
<% if show_feedback_form? %>
<div id="feedback-form" class="feedback-form-container collapse">
<%= render "shared/feedback_forms/form" %>
</div>
<% end %>
<%= yield %>
</div>
</div>
Expand Down
41 changes: 41 additions & 0 deletions app/views/shared/feedback_forms/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<div class="container">
<%= form_tag feedback_form_path, method: :post, class:"form-horizontal feedback-form", role:"form" do %>
<div class="col-sm-6 col-sm-offset-2">
<div class="col-sm-offset-3">
<%= render "shared/feedback_forms/reporting_from" %>
</div>
</div>
<span style="display:none;visibility:hidden;">
<%= label_tag(:email_address, 'Ignore this text box. It is used to detect spammers. If you enter anything into this text box, your message will not be sent.') %><br/>
<%= email_field_tag :email_address %><br/>
<%= text_field_tag :user_agent %>
<%= text_field_tag :viewport %>
</span>
<div class="col-sm-6 col-sm-offset-2">
<div class="form-group">
<%= label_tag(:message, 'Message', class:"col-sm-3 control-label") %>
<div class="col-sm-9">
<%= text_area_tag :message, "", rows:"5", class:"form-control" %>
</div>
</div>
<div class="form-group">
<%= label_tag(:name, 'Your name', class:"col-sm-3 control-label") %>
<div class="col-sm-9">
<%= text_field_tag :name, "", class:"form-control" %>
</div>
</div>
<div class="form-group">
<%= label_tag(:to, 'Your email', class:"col-sm-3 control-label") %>
<div class="col-sm-9">
<%= email_field_tag :to, "", class:"form-control" %>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-primary">Send</button>
<%= link_to "Cancel", :back, class:"cancel-link", data: {toggle:"collapse", target:"#feedback-form"} %>
</div>
</div>
</div>
<% end %>
</div>
2 changes: 2 additions & 0 deletions app/views/shared/feedback_forms/_reporting_from.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reporting from: <span class="reporting-from-field"><%= request.referer %></span>
<%= hidden_field_tag :url, request.referer, class:"reporting-from-field" %>
45 changes: 2 additions & 43 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,6 @@

resources :reserves


# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end

# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end

# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end

# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end

# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => 'welcome#index'

# See how all your routes lay out with "rake routes"

# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id))(.:format)'
resource :feedback_form, path: 'feedback', only: [:new, :create]
get 'feedback' => 'feedback_forms#new'
end
1 change: 1 addition & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ email:
from: "[email protected]"
reports: "[email protected]"
allforms: "[email protected]"
feedback:

email_mapping:
"ART-RESV": "[email protected]"
Expand Down

0 comments on commit 20e670d

Please sign in to comment.