Create a gist now

Instantly share code, notes, and snippets.

@rogeruiz /subscribe.js Secret
Last active Aug 29, 2015

What would you like to do?
In-Video Subscribe for the Condé Nast Video Player
/* JS + ERB */
/*jshint ignore:start*/
<%= raw @callback %>(
/*jshint ignore:end*/
// README: The Form Popup is hardcoded here.
'<%= j render(partial: "annotations/subscribe_form") %>',
function($container, player) { // onLoad
var destroyTimeoutInMilliseconds = 4500;
var selectors = {
annotation: '.js-annotation',
closeButton: '.js-subscribe-close-button',
input: '.js-subscribe-input',
form: '.js-subscribe-form',
bubble: '.js-subscribe-bubble',
submitButton: '.js-subscribe-submit',
success: '.js-subscribe-success'
};
var $annotation = $container.find(selectors.annotation);
var buildUrl = function() {
var url = [];
url.push('<%= Playerservice::Application.config.api_uri %>');
url.push('<%= Playerservice::Application.config.api_subscribe_path %>');
return url.join('/');
};
var validateEmail = function(email) {
return /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/i.test(email);
};
var SubscribePanel = {
durationInDays: 100,
init: function() {
// With Doug's new design updates for the Form design, require some JS
// centering to work properly. This method does just that.
if ($annotation.hasClass('cne-annotation--form')) {
this.centerForm();
}
this.setupPanelEvents();
},
centerForm: function() {
// This maxWidth is taken from the PSD.
var maxWidth = 721;
var $player = _cne.$(player.player.el());
var playerWidth = $player.width();
var formWidthAsPercentage = .9013;
var formWidth = Math.round(playerWidth * formWidthAsPercentage);
var $form = $annotation.find(selectors.form);
if (formWidth < maxWidth) {
$form.css({
marginLeft: '-' + (Math.round(formWidth / 2)) + 'px'
});
}
},
subscribeEndpoint: buildUrl(),
ajaxRequest: function(email, submitCallback) {
var url = '//' + this.subscribeEndpoint;
if (window.XDomainRequest) {
// You have entered the MSHell. Please proceed with the caution that
// drives your heart when walking on eggshells.
// Let's begin with a new XDR since we didn't think we needed one.
var xdr = new XDomainRequest();
// Let's handle every SINGLE event thrown at us.
xdr.onload = function() {
var response = this.responseText;
submitCallback();
};
// I mean all of them.
xdr.onerror = function() {
var response = this.responseText;
};
// No arguments being assigned? Oh, that's because MS doesn't think you
// need them. Let's just lose scope how we're used to anyway...
xdr.onprogress = function() {
var response = this.responseText;
};
// This last one is helpful sometimes, so I take back my sarcasm.
xdr.ontimeout = function() {
var response = this.responseText;
console.log('The XDR Response took longer than the expected ' + (xdr.timeout / 1000) + ' seconds allotted.');
};
// Let's let this thing wait a while, since time is an illusion anyway.
xdr.timeout = 10000;
// Finally we open it and stuff it's dirty little method with parameters.
xdr.open('post', url + _cne.$.param({
email: email,
vars: {
form_location: 'InVideoSubscribe',
source: 'InVideo'
}
}));
// Finally, again. Let's send this thing out of here.
window.setTimeout(function() {
// But let's not do it right away. MSHell is a strange place.
xdr.send();
}, 0);
} else {
_cne.$.ajax({
url: url,
type: 'POST',
data: {
email: email,
vars: {
form_location: 'InVideoSubscribe',
source: 'InVideo'
}
},
success: function(response) {
if (!response.error) {
submitCallback();
}
},
error: function(response) {
console.log(response.toString());
}
});
}
},
submitEmail: function(email) {
var self = this;
var counter = 0;
// README: There can be some network latency, so let's give the
// user some feedback that the submit is happening.
this.submitLoadingInterval = window.setInterval(function() {
if (counter > 2) {
counter = 0;
}
switch(counter) {
case 0:
_cne.$('.js-subscribe-submit').val('.');
break;
case 1:
_cne.$('.js-subscribe-submit').val('..');
break;
case 2:
_cne.$('.js-subscribe-submit').val('...');
}
counter++
}, 200);
this.ajaxRequest(email, function() {
window.clearTimeout(self.submitLoadingInterval);
self.subscribeSuccessful();
});
},
setCookie: function() {
_cne.util.CookieHelper.create('cne_invideo_subscribe', true, this.durationInDays);
},
subscribeSuccessful: function() {
this.setCookie();
player.sendAnalyticsEvent('InVideoSubscribe', 'Submit', {
eventLabel: player.config.video.title
});
var self = this;
if (player.isMobile()) {
$annotation.find(selectors.form).remove();
} else {
$annotation.find(selectors.form).removeClass('is-active is-focused')
}
$annotation.addClass('subscribe-complete');
player.play();
window.setTimeout(function() {
$annotation.fadeOut(300, function() {
self.destroyPanel();
});
}, destroyTimeoutInMilliseconds);
},
setupPanelEvents: function() {
var self = this;
$annotation.on('click', selectors.closeButton, function(event) {
event.stopPropagation();
if (!player.isPlaying()) {
player.play();
}
self.setCookie();
self.destroyPanel();
});
$annotation.on('focus', selectors.input, function(event) {
event.stopPropagation();
event.preventDefault();
if (player.isPlaying()) {
player.pause();
}
$annotation.find(selectors.form).addClass('is-focused');
});
$annotation.on('blur', selectors.input, function(event) {
event.stopPropagation();
event.preventDefault();
if (!player.isPlaying()) {
player.play();
}
$annotation.find(selectors.form).removeClass('is-focused');
});
$annotation.on('submit', selectors.form, function(event) {
event.stopPropagation();
event.preventDefault();
var email = $annotation.find(selectors.input).val();
if (validateEmail(email)) {
self.submitEmail(email);
}
});
$annotation.on('keyup change', selectors.input, function(event) {
var $el = _cne.$(this);
if (validateEmail($el.val())) {
$annotation.find(selectors.submitButton).removeAttr('disabled');
} else {
$annotation.find(selectors.submitButton).attr('disabled', 'disabled');
}
});
$annotation.on('click', selectors.submitButton, function(event) {
event.stopPropagation();
event.preventDefault();
$annotation.find(selectors.form).submit();
});
$annotation.on('click', selectors.bubble, function(event) {
event.stopPropagation();
var $el = _cne.$(this);
$annotation.addClass('backdrop-active');
player.pause();
$el.hide();
$annotation.find(selectors.form).addClass('is-active');
});
},
destroyPanel: function() {
player.annotationLoader.destroyAnnotations();
}
};
SubscribePanel.init();
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment