Attendize/public/assets/javascript/app-public.js

405 lines
15 KiB
JavaScript

$(function() {
$('form.ajax').on('submit', function(e) {
e.preventDefault();
e.stopImmediatePropagation();
var $form =
$(this),
$submitButton = $form.find('input[type=submit]'),
ajaxFormConf = {
delegation: true,
beforeSerialize: function(jqForm, options) {
window.doSubmit = true;
clearFormErrors(jqForm[0]);
toggleSubmitDisabled($submitButton);
},
beforeSubmit: function() {
$submitButton = $form.find('input[type=submit]');
toggleSubmitDisabled($submitButton);
return window.doSubmit;
},
error: function(data, statusText, xhr, $form) {
$submitButton = $form.find('input[type=submit]');
// Form validation error.
if (422 == data.status) {
processFormErrors($form, $.parseJSON(data.responseText));
return;
}
toggleSubmitDisabled($submitButton);
showMessage(lang("whoops"));
},
success: function(data, statusText, xhr, $form) {
var $submitButton = $form.find('input[type=submit]');
if (data.message) {
showMessage(data.message);
}
switch (data.status) {
case 'success':
if (data.redirectUrl) {
if(data.redirectData) {
$.redirectPost(data.redirectUrl, data.redirectData);
} else {
document.location.href = data.redirectUrl;
}
}
break;
case 'error':
if (data.messages) {
processFormErrors($form, data.messages);
return;
}
break;
default:
break;
}
toggleSubmitDisabled($submitButton);
},
dataType: 'json'
};
toggleSubmitDisabled($submitButton);
if ($form.hasClass('payment-form') && !$('#pay_offline').is(":checked")) {
clearFormErrors($('.payment-form'));
Stripe.setPublishableKey($form.data('stripe-pub-key'));
var
noErrors = true,
$cardNumber = $('.card-number'),
$cardName = $('.card-name'),
$cvcNumber = $('.card-cvc'),
$expiryMonth = $('.card-expiry-month'),
$expiryYear = $('.card-expiry-year');
if (!Stripe.validateCardNumber($cardNumber.val())) {
showFormError($cardNumber, lang("credit_card_error"));
noErrors = false;
}
if (!Stripe.validateCVC($cvcNumber.val())) {
showFormError($cardNumber, lang("cvc_error"));
noErrors = false;
}
if (!Stripe.validateExpiry($expiryMonth.val(), $expiryYear.val())) {
showFormError($cardNumber, lang("expiry_error"));
showFormError($expiryYear, '');
noErrors = false;
}
if (noErrors) {
Stripe.card.createToken({
name: $cardName.val(),
number: $cardNumber.val(),
cvc: $cvcNumber.val(),
exp_month: $expiryMonth.val(),
exp_year: $expiryYear.val()
},
function(status, response) {
if (response.error) {
clearFormErrors($('.payment-form'));
if(response.error.param.length>0)
showFormError($('*[data-stripe=' + response.error.param + ']', $('.payment-form')), response.error.message);
else
showMessage(response.error.message);
toggleSubmitDisabled($submitButton);
} else {
var token = response.id;
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
$form.ajaxSubmit(ajaxFormConf);
}
});
} else {
showMessage(lang("card_validation_error"));
toggleSubmitDisabled($submitButton);
}
} else {
$form.ajaxSubmit(ajaxFormConf);
}
});
$('a').smoothScroll({
offset: -60
});
/* Scroll to top */
$(window).scroll(function() {
if ($(this).scrollTop() > 100) {
$('.totop').fadeIn();
} else {
$('.totop').fadeOut();
}
});
$('#organiserHead').on('click', function(e) {
e.stopImmediatePropagation();
$('#organiser')[0].scrollIntoView();
});
$('#contact_organiser').on('click', function(e) {
e.preventDefault();
$('.contact_form').slideToggle();
});
$('#mirror_buyer_info').on('click', function(e) {
$('.ticket_holder_first_name').val($('#order_first_name').val());
$('.ticket_holder_last_name').val($('#order_last_name').val());
$('.ticket_holder_email').val($('#order_email').val());
});
$('.card-number').payment('formatCardNumber');
$('.card-cvc').payment('formatCardCVC');
$('#pay_offline').change(function () {
$('.online_payment').toggle(!this.checked);
$('.offline_payment').toggle(this.checked);
// Disable CC form inputs to prevent Chrome trying to validate hidden fields
$('.online_payment input, .online_payment select').attr('disabled', this.checked);
}).change();
// Apply access code here to unlock hidden tickets
$('#apply_access_code').click(function(e) {
var $clicked = $(this);
// Hide any previous errors
$clicked.closest('.form-group')
.removeClass('has-error');
var url = $clicked.closest('.has-access-codes').data('url');
var data = {
'access_code': $('#unlock_code').val(),
'_token': $('input:hidden[name=_token]').val()
};
$.post(url, data, function(response) {
if (response.status === 'error') {
// Show any access code errors
$clicked.closest('.form-group').addClass('has-error');
showMessage(response.message);
return;
}
$clicked.closest('.has-access-codes').before(response);
$('#unlock_code').val('');
$clicked.closest('.has-access-codes').remove();
});
});
});
function processFormErrors($form, errors)
{
$.each(errors, function (index, error)
{
var selector = (index.indexOf(".") >= 0) ? '.' + index.replace(/\./g, "\\.") : ':input[name=' + index + ']';
var $input = $(selector, $form);
if ($input.prop('type') === 'file') {
$('#input-' + $input.prop('name')).append('<div class="help-block error">' + error + '</div>')
.parent()
.addClass('has-error');
} else {
if($input.parent().hasClass('input-group')) {
$input = $input.parent();
}
$input.after('<div class="help-block error">' + error + '</div>')
.parent()
.addClass('has-error');
}
});
var $submitButton = $form.find('input[type=submit]');
toggleSubmitDisabled($submitButton);
}
/**
* Toggle a submit button disabled/enabled
*
* @param element $submitButton
* @returns void
*/
function toggleSubmitDisabled($submitButton) {
if ($submitButton.hasClass('disabled')) {
$submitButton.attr('disabled', false)
.removeClass('disabled')
.val($submitButton.data('original-text'));
return;
}
$submitButton.data('original-text', $submitButton.val())
.attr('disabled', true)
.addClass('disabled')
.val(lang("processing"));
}
/**
* Clears given form of any error classes / messages
*
* @param {Element} $form
* @returns {void}
*/
function clearFormErrors($form) {
$($form)
.find('.error.help-block')
.remove();
$($form).find(':input')
.parent()
.removeClass('has-error');
$($form).find(':input')
.parent().parent()
.removeClass('has-error');
}
function showFormError($formElement, message) {
$formElement.after('<div class="help-block error">' + message + '</div>')
.parent()
.addClass('has-error');
}
/**
* Shows users a message.
* Currently uses humane.js
*
* @param string message
* @returns void
*/
function showMessage(message) {
humane.log(message, {
timeoutAfterMove: 3000,
waitForMove: true
});
}
function hideMessage() {
humane.remove();
}
/**
* Counts down to the given number of seconds
*
* @param element $element
* @param int seconds
* @returns void
*/
function setCountdown($element, seconds) {
var endTime, mins, msLeft, time, twoMinWarningShown = false;
function twoDigits(n) {
return (n <= 9 ? "0" + n : n);
}
function updateTimer() {
msLeft = endTime - (+new Date);
if (msLeft < 1000) {
alert(lang("time_run_out"));
location.reload();
} else {
if (msLeft < 120000 && !twoMinWarningShown) {
showMessage(lang("just_2_minutes"));
twoMinWarningShown = true;
}
time = new Date(msLeft);
mins = time.getUTCMinutes();
$element.html('<b>' + mins + ':' + twoDigits(time.getUTCSeconds()) + '</b>');
setTimeout(updateTimer, time.getUTCMilliseconds() + 500);
}
}
endTime = (+new Date) + 1000 * seconds + 500;
updateTimer();
}
$.extend(
{
redirectPost: function(location, args)
{
var form = '';
$.each( args, function( key, value ) {
value = value.split('"').join('\"')
form += '<input type="hidden" name="'+key+'" value="'+value+'">';
});
$('<form action="' + location + '" method="POST">' + form + '</form>').appendTo($(document.body)).submit();
}
});
/*!
* Smooth Scroll - v1.4.13 - 2013-11-02
* https://github.com/kswedberg/jquery-smooth-scroll
* Copyright (c) 2013 Karl Swedberg
* Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT)
*/
(function(t) {
function e(t) {
return t.replace(/(:|\.)/g, "\\$1")
}
var l = "1.4.13", o = {}, s = {exclude: [], excludeWithin: [], offset: 0, direction: "top", scrollElement: null, scrollTarget: null, beforeScroll: function() {
}, afterScroll: function() {
}, easing: "swing", speed: 400, autoCoefficent: 2, preventDefault: !0}, n = function(e) {
var l = [], o = !1, s = e.dir && "left" == e.dir ? "scrollLeft" : "scrollTop";
return this.each(function() {
if (this != document && this != window) {
var e = t(this);
e[s]() > 0 ? l.push(this) : (e[s](1), o = e[s]() > 0, o && l.push(this), e[s](0))
}
}), l.length || this.each(function() {
"BODY" === this.nodeName && (l = [this])
}), "first" === e.el && l.length > 1 && (l = [l[0]]), l
};
t.fn.extend({scrollable: function(t) {
var e = n.call(this, {dir: t});
return this.pushStack(e)
}, firstScrollable: function(t) {
var e = n.call(this, {el: "first", dir: t});
return this.pushStack(e)
}, smoothScroll: function(l, o) {
if (l = l || {}, "options" === l)
return o ? this.each(function() {
var e = t(this), l = t.extend(e.data("ssOpts") || {}, o);
t(this).data("ssOpts", l)
}) : this.first().data("ssOpts");
var s = t.extend({}, t.fn.smoothScroll.defaults, l), n = t.smoothScroll.filterPath(location.pathname);
return this.unbind("click.smoothscroll").bind("click.smoothscroll", function(l) {
var o = this, r = t(this), i = t.extend({}, s, r.data("ssOpts") || {}), c = s.exclude, a = i.excludeWithin, f = 0, h = 0, u = !0, d = {}, p = location.hostname === o.hostname || !o.hostname, m = i.scrollTarget || (t.smoothScroll.filterPath(o.pathname) || n) === n, S = e(o.hash);
if (i.scrollTarget || p && m && S) {
for (; u && c.length > f; )
r.is(e(c[f++])) && (u = !1);
for (; u && a.length > h; )
r.closest(a[h++]).length && (u = !1)
} else
u = !1;
u && (i.preventDefault && l.preventDefault(), t.extend(d, i, {scrollTarget: i.scrollTarget || S, link: o}), t.smoothScroll(d))
}), this
}}), t.smoothScroll = function(e, l) {
if ("options" === e && "object" == typeof l)
return t.extend(o, l);
var s, n, r, i, c = 0, a = "offset", f = "scrollTop", h = {}, u = {};
"number" == typeof e ? (s = t.extend({link: null}, t.fn.smoothScroll.defaults, o), r = e) : (s = t.extend({link: null}, t.fn.smoothScroll.defaults, e || {}, o), s.scrollElement && (a = "position", "static" == s.scrollElement.css("position") && s.scrollElement.css("position", "relative"))), f = "left" == s.direction ? "scrollLeft" : f, s.scrollElement ? (n = s.scrollElement, /^(?:HTML|BODY)$/.test(n[0].nodeName) || (c = n[f]())) : n = t("html, body").firstScrollable(s.direction), s.beforeScroll.call(n, s), r = "number" == typeof e ? e : l || t(s.scrollTarget)[a]() && t(s.scrollTarget)[a]()[s.direction] || 0, h[f] = r + c + s.offset, i = s.speed, "auto" === i && (i = h[f] || n.scrollTop(), i /= s.autoCoefficent), u = {duration: i, easing: s.easing, complete: function() {
s.afterScroll.call(s.link, s)
}}, s.step && (u.step = s.step), n.length ? n.stop().animate(h, u) : s.afterScroll.call(s.link, s)
}, t.smoothScroll.version = l, t.smoothScroll.filterPath = function(t) {
return t.replace(/^\//, "").replace(/(?:index|default).[a-zA-Z]{3,4}$/, "").replace(/\/$/, "")
}, t.fn.smoothScroll.defaults = s
})(jQuery);