Created
February 1, 2011 03:07
-
-
Save balupton/805353 to your computer and use it in GitHub Desktop.
Ajaxify a Campaign Monitor Subscribe Form without the need for a server-side proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Ajaxify a Campaign Monitor Subscribe Form | |
* without the need for a server-side proxy | |
* @author Benjamin Arthur Lupton | |
* @license Public Domain | |
*/ | |
$.fn.cmAjaxify = $.fn.cmAjaxify||function(options){ | |
// Prepare Options | |
options = options||{}; | |
options.html5ize = options.html5ize||false; | |
options.submitTitle = options.submitTitle||''; | |
options.submitCallback = options.submitCallback||null; | |
options.loadCallback = options.loadCallback||null; | |
options.scriptUrl = options.scriptUrl||null; | |
options.stylesheetUrl = options.stylesheetUrl||null; | |
options.appendTo = options.appendTo||undefined; | |
// Check Options | |
if ( typeof options.appendTo === 'undefined' ) { | |
throw new Error('You need to specify the appendTo option'); | |
} | |
options.appendTo = $(options.appendTo); | |
// Fetch Elements | |
var | |
$cmForm = $(this), | |
$iframe = $('<iframe class="subscribe"></iframe>').appendTo(options.appendTo), | |
iframeContentWindow = $iframe.get(0).contentWindow, | |
ajaxFormHtml = | |
(options.scriptUrl ? '<script type="text/javascript" src="'+options.scriptUrl+'"></script>' : '')+ | |
(options.stylesheetUrl ? '<link type="text/css" rel="stylesheet" media="screen" href="'+options.stylesheetUrl+'"/>' : '')+ | |
$cmForm.outerHtml(), | |
loadTimeout = null; | |
// Ensure the iframe has loaded before we write to it | |
// Fixes firefox issue | |
$iframe.load(function(){ | |
// Clear timeout | |
clearTimeout(timeout); | |
timeout = null; | |
// Unbind so we don't reset the iframe on submit | |
$iframe.unbind(); | |
// Fetch Elements | |
var | |
$ajaxForm = $(iframeContentWindow.document.body).html(ajaxFormHtml); | |
$texts = $ajaxForm.find(':text'), | |
$submit = $ajaxForm.find(':submit'); | |
// html5ize | |
if ( options.html5ize ) { | |
// Placeholders | |
$texts.addClass('text').each(function(){ | |
// Fetch Elements | |
var | |
$input = $(this), | |
$labelWrap = $input.parent().prev(), | |
$label = $labelWrap.children('label'); | |
// Add Placeholder | |
$input.placeholder($label.text().replace(':','')); | |
$labelWrap.hide(); | |
}); | |
// Clean Submit | |
$submit.parent().replaceWith($submit); | |
} | |
// Clean Submit | |
$submit.parents('div:first').addClass('submit-wrap'); | |
$submit.addClass('submit').attr('title',options.submitTitle).val('Subscribe'); | |
// Submit Handler | |
$ajaxForm.find('form').unbind().submit(function(event){ | |
// Validate | |
var valid = true; | |
$texts.each(function(){ | |
var $input = $(this); | |
if ( !$input.val() || $input.val() === $input.placeholder() ) { | |
valid = false; | |
$input.flash(); | |
} | |
}); | |
// Validate Email | |
if ( valid ) { | |
var | |
$emailField = $texts.eq(1), | |
emailValue = $emailField.val(), | |
emailFilter = /^[^\@]+\@.+$/ | |
; | |
if ( !emailFilter.test(emailValue) ) { | |
valid = false; | |
$emailField.flash(); | |
} | |
} | |
// Check | |
if ( !valid ) { | |
event.stopPropagation(); | |
event.preventDefault(); | |
return false; | |
} | |
// Submit Handler | |
if ( options.submitCallback ) { | |
return options.submitCallback.apply(this,arguments); | |
} | |
// Leave Submit Closure | |
return true; | |
}); | |
// Load Handler | |
if ( options.loadCallback ) { | |
return options.loadCallback.apply(this,arguments); | |
} | |
// Leave Load Closure | |
return true; | |
}); | |
// Ensure works in Chrome | |
timeout = setTimeout(function(){ | |
$iframe.trigger('load'); | |
},500); | |
// Leave cmAjaxify Closure | |
return $cmForm; | |
}; |
Currently the validation is only client side. To obtain server side validation, Campaign Monitor will have to utilise something like <script>if ( typeof window.parent !== 'undefined' ) window.parent.cmSuccess = true</script>
inside their page. Then server-side we could hook into the iframe's onload event, check for the set variable and know if it passed or not and handle appropriately, CM could even set a error message that should be displayed to the user. That way we really could have a full fledged proper solution without the need for a proxy.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Locations to the dependencies:
$.fn.placeholder
- https://gist.github.com/805359$.fn.flash
- https://gist.github.com/805639$.fn.outerHtml
- https://gist.github.com/805640