Skip to content

Instantly share code, notes, and snippets.

@balupton
Created February 1, 2011 03:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save balupton/805353 to your computer and use it in GitHub Desktop.
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
/**
* 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;
};
@balupton
Copy link
Author

balupton commented Feb 1, 2011

Locations to the dependencies:

@balupton
Copy link
Author

balupton commented Feb 1, 2011

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