I render an alert bar as a partial at the top of the screen that gets shown to the user for success/failure/notice flash messages.
I finally have it working for most scenarios, but the code itself is repetitive for a few parts and I am not sure how I can split it up more efficiently since I am relatively new to all of this. My goal is to try not to repeat myself if possible or at least to minimize how much is repeated.
For instance, is there a way to place some of the javascript into a re-useable partial or helper function? Are there other obvious ways of making this code less repetitious?
I’m not comfortable enough yet with Rails/Ruby to understand how to improve the code, so any tips you can provide are greatly appreciated!
/ top alert area
#topAlertBar.shadow_medium.soft-hidden
- if flash.empty? && !current_user.confirmed?
- # User has yet to confirm their account
- # and there AREN'T any flash messages to show
#alertBarOffset.colordark.soft-hidden
/ placeholder for alert bar offset
:javascript
// Set the flash box content
$('#topAlertBar').html('Please confirm your account by following the instructions sent to #{current_user.email}. To resend your confirmation email, #{escape_javascript(link_to("click here", user_resend_confirmation_path(current_user), :class => "inlinelink", :method => :post, :remote => true))} #{escape_javascript(image_tag("ajaxOrange.gif", :class => "soft-hidden mls mbs"))}.');
// Slides down the top alert bar after page load
$('#topAlertBar, #alertBarOffset').delay(250).slideDown("fast");
// Shows & hides AJAX loading GIF when necessary
$('#topAlertBar a').click(function() {
$(document).bind('ajaxSend', function(e, request, options) {
$("#topAlertBar img").show();
});
$(document).bind('ajaxComplete', function(e, request, options) {
$(document).unbind('ajaxSend', 'ajaxComplete');
$("#topAlertBar img").hide();
});
});
- elsif !flash.empty? && !current_user.confirmed?
- # User has yet to confirm their account
- # and there ARE flash messages to show
#alertBarOffset.colordark.soft-hidden
/ placeholder for alert bar offset
- [:error, :success, :notice].each do |key|
- unless flash[key].blank?
- @msg = flash[key]
- @key = key
:javascript
// Set the flash box content
var $that = $('#topAlertBar');
$that.html('#{@msg}').addClass('#{@key}').delay(250).slideDown("fast", function() {
$(this).delay(2000).slideUp("fast", function () {
// Remove any CSS modifiers
$that.removeClass('#{@key}');
// Set the flash box content
$('#topAlertBar').html('Please confirm your account by following the instructions sent to #{current_user.email}. To resend your confirmation email, #{escape_javascript(link_to("click here", user_resend_confirmation_path(current_user), :class => "inlinelink", :method => :post, :remote => true))} #{escape_javascript(image_tag("ajaxOrange.gif", :class => "soft-hidden mls mbs"))}.');
// Slides down the top alert bar after page load
$('#topAlertBar, #alertBarOffset').slideDown("fast");
// Shows & hides AJAX loading GIF when necessary
$('#topAlertBar a').click(function() {
$(document).bind('ajaxSend', function(e, request, options) {
$("#topAlertBar img").show();
});
$(document).bind('ajaxComplete', function(e, request, options) {
$(document).unbind('ajaxSend', 'ajaxComplete');
$("#topAlertBar img").hide();
});
});
});
});
- elsif !flash.empty?
- # User is confirmed
- # and there ARE flash messages to show
- [:error, :success, :notice].each do |key|
- unless flash[key].blank?
- @msg = flash[key]
- @key = key
:javascript
// Set the flash box content
var $that = $('#topAlertBar');
$that.html('#{@msg}').addClass('#{@key}').delay(250).slideDown("fast", function() {
$(this).delay(2000).slideUp("fast");
});
I ended up taking a different approach than what Jesse recommended, but he still helped get me thinking about ways to refactor the code. Here is the end result which is as DRY as I could get it without completely changing how I already had it implemented.
Hopefully this will help someone else who stumbles upon this question in the future.
In my ApplicationHelper (this is modified somewhat from the original question so it now works for my validation errors as well as regular flash messages)
In my main layout file, I’m just doing:
In the top alert bar file
In the confirm_user partial
And finally, I moved this to my main js file
});