/*global siteglobals, module, lang, django*/
/* PRETIX WIDGET BEGINS HERE */
/* This is embedded in an isolation wrapper that exposes siteglobals as the global
scope. */
window.PretixWidget = {
'build_widgets': true,
'widget_data': {
'referer': location.href
}
};
var Vue = module.exports;
Vue.component('resize-observer', VueResize.ResizeObserver)
var strings = {
'sold_out': django.pgettext('widget', 'Sold out'),
'buy': django.pgettext('widget', 'Buy'),
'register': django.pgettext('widget', 'Register'),
'reserved': django.pgettext('widget', 'Reserved'),
'free': django.pgettext('widget', 'FREE'),
'price_from': django.pgettext('widget', 'from %(currency)s %(price)s'),
'tax_incl': django.pgettext('widget', 'incl. %(rate)s% %(taxname)s'),
'tax_plus': django.pgettext('widget', 'plus %(rate)s% %(taxname)s'),
'tax_incl_mixed': django.pgettext('widget', 'incl. taxes'),
'tax_plus_mixed': django.pgettext('widget', 'plus taxes'),
'quota_left': django.pgettext('widget', 'currently available: %s'),
'voucher_required': django.pgettext('widget', 'Only available with a voucher'),
'order_min': django.pgettext('widget', 'minimum amount to order: %s'),
'exit': django.pgettext('widget', 'Close ticket shop'),
'loading_error': django.pgettext('widget', 'The ticket shop could not be loaded.'),
'cart_error': django.pgettext('widget', 'The cart could not be created. Please try again later'),
'waiting_list': django.pgettext('widget', 'Waiting list'),
'cart_exists': django.pgettext('widget', 'You currently have an active cart for this event. If you select more' +
' products, they will be added to your existing cart.'),
'resume_checkout': django.pgettext('widget', 'Resume checkout'),
'redeem_voucher': django.pgettext('widget', 'Redeem a voucher'),
'redeem': django.pgettext('widget', 'Redeem'),
'voucher_code': django.pgettext('widget', 'Voucher code'),
'close': django.pgettext('widget', 'Close'),
'continue': django.pgettext('widget', 'Continue'),
'variations': django.pgettext('widget', 'See variations'),
'back_to_list': django.pgettext('widget', 'Choose a different event'),
'back_to_dates': django.pgettext('widget', 'Choose a different date'),
'back': django.pgettext('widget', 'Back'),
'next_month': django.pgettext('widget', 'Next month'),
'previous_month': django.pgettext('widget', 'Previous month'),
'show_seating': django.pgettext('widget', 'Open seat selection'),
'days': {
'MO': django.gettext('Mo'),
'TU': django.gettext('Tu'),
'WE': django.gettext('We'),
'TH': django.gettext('Th'),
'FR': django.gettext('Fr'),
'SA': django.gettext('Sa'),
'SU': django.gettext('Su'),
},
'months': {
'01': django.gettext('January'),
'02': django.gettext('February'),
'03': django.gettext('March'),
'04': django.gettext('April'),
'05': django.gettext('May'),
'06': django.gettext('June'),
'07': django.gettext('July'),
'08': django.gettext('August'),
'09': django.gettext('September'),
'10': django.gettext('October'),
'11': django.gettext('November'),
'12': django.gettext('December'),
}
};
var setCookie = function (cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
};
var getCookie = function (name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift() || null;
else return null;
};
var padNumber = function(number, size) {
var s = String(number);
while (s.length < (size || 2)) {s = "0" + s;}
return s;
};
/* HTTP API Call helpers */
var api = {
'_getXHR': function () {
try {
return new window.XMLHttpRequest();
} catch (e) {
// explicitly bubble up the exception if not found
return new window.ActiveXObject('Microsoft.XMLHTTP');
}
},
'_getJSON': function (endpoint, callback, err_callback) {
var xhr = api._getXHR();
xhr.open("GET", endpoint, true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(JSON.parse(xhr.responseText), xhr);
} else {
err_callback(xhr, e);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
err_callback(xhr, e);
};
xhr.send(null);
},
'_postFormJSON': function (endpoint, form, callback, err_callback) {
var params = [].filter.call(form.elements, function (el) {
return (el.type !== 'checkbox' && el.type !== 'radio') || el.checked;
})
.filter(function (el) {
return !!el.name && !!el.value;
})
.filter(function (el) {
return !el.disabled;
})
.map(function (el) {
return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
}).join('&');
var xhr = api._getXHR();
xhr.open("POST", endpoint, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(JSON.parse(xhr.responseText));
} else {
err_callback(xhr, e);
}
}
};
xhr.onerror = function (e) {
err_callback(xhr, e);
};
xhr.send(params);
}
};
var makeid = function (length) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
var site_is_secure = function () {
return /https.*/.test(document.location.protocol)
};
var widget_id = makeid(16);
/* Vue Components */
Vue.component('availbox', {
template: ('
'),
props: {
item: Object,
variation: Object
},
computed: {
input_name: function () {
if (this.item.has_variations) {
return 'variation_' + this.item.id + '_' + this.variation.id;
} else {
return 'item_' + this.item.id;
}
},
order_max: function () {
return this.item.has_variations ? this.variation.order_max : this.item.order_max;
},
avail: function () {
return this.item.has_variations ? this.variation.avail : this.item.avail;
},
waiting_list_show: function () {
return this.avail[0] < 100 && this.$root.waiting_list_enabled;
},
waiting_list_url: function () {
if (this.item.has_variations) {
return this.$root.target_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id + '&var=' + this.variation.id + '&widget_data=' + escape(this.$root.widget_data_json);
} else {
return this.$root.target_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id + '&widget_data=' + escape(this.$root.widget_data_json);
}
}
}
});
Vue.component('pricebox', {
template: (''),
props: {
price: Object,
free_price: Boolean,
field_name: String,
original_price: String
},
computed: {
display_price: function () {
if (this.$root.display_net_prices) {
return floatformat(parseFloat(this.price.net), 2);
} else {
return floatformat(parseFloat(this.price.gross), 2);
}
},
display_price_nonlocalized: function () {
if (this.$root.display_net_prices) {
return parseFloat(this.price.net).toFixed(2);
} else {
return parseFloat(this.price.gross).toFixed(2);
}
},
original_line: function () {
return this.$root.currency + " " + floatformat(parseFloat(this.original_price), 2);
},
priceline: function () {
if (this.price.gross === "0.00") {
return strings.free;
} else {
return this.$root.currency + " " + this.display_price;
}
},
taxline: function () {
if (this.$root.display_net_prices) {
if (this.price.includes_mixed_tax_rate) {
return strings.tax_plus_mixed;
} else {
return django.interpolate(strings.tax_plus, {
'rate': autofloatformat(this.price.rate, 2),
'taxname': this.price.name
}, true);
}
} else {
if (this.price.includes_mixed_tax_rate) {
return strings.tax_incl_mixed;
} else {
return django.interpolate(strings.tax_incl, {
'rate': autofloatformat(this.price.rate, 2),
'taxname': this.price.name
}, true);
}
}
}
}
});
Vue.component('variation', {
template: (''),
props: {
variation: Object,
item: Object,
},
computed: {
orig_price: function () {
if (this.variation.original_price) {
return this.variation.original_price;
}
return this.item.original_price;
},
quota_left_str: function () {
return django.interpolate(strings["quota_left"], [this.variation.avail[1]]);
},
}
});
Vue.component('item', {
template: (''
+ '
'
+ '
'
+ '
'
+ '
'
+ '
'
+ '
'
+ '
'
+ ''
+ ''
+ '
'
+ '
'),
props: {
item: Object,
},
data: function () {
return {
expanded: this.$root.show_variations_expanded
};
},
methods: {
expand: function () {
this.expanded = !this.expanded;
}
},
computed: {
classObject: function () {
return {
'pretix-widget-item': true,
'pretix-widget-item-with-picture': !!this.item.picture,
'pretix-widget-item-with-variations': this.item.has_variations
}
},
varClasses: function () {
return {
'pretix-widget-item-variations': true,
'pretix-widget-item-variations-expanded': this.expanded,
}
},
min_order_str: function () {
return django.interpolate(strings["order_min"], [this.item.order_min]);
},
quota_left_str: function () {
return django.interpolate(strings["quota_left"], [this.item.avail[1]]);
},
show_toggle: function () {
return this.item.has_variations && !this.$root.show_variations_expanded;
},
pricerange: function () {
if (this.item.free_price) {
return django.interpolate(strings.price_from, {
'currency': this.$root.currency,
'price': floatformat(this.item.min_price, 2)
}, true);
} else if (this.item.min_price !== this.item.max_price) {
return this.$root.currency + " " + floatformat(this.item.min_price, 2) + " – "
+ floatformat(this.item.max_price, 2);
} else if (this.item.min_price === "0.00" && this.item.max_price === "0.00") {
return strings.free;
} else {
return this.$root.currency + " " + floatformat(this.item.min_price, 2);
}
},
}
});
Vue.component('category', {
template: (''),
props: {
category: Object
}
});
var shared_methods = {
buy: function (event) {
if (this.$root.useIframe) {
if (event) {
event.preventDefault();
}
} else {
return;
}
if (this.$root.is_button && this.$root.items.length === 0) {
if (this.$root.voucher_code) {
this.voucher_open(this.$root.voucher_code);
} else {
this.resume();
}
} else {
var url = this.$root.formTarget + "&locale=" + lang + "&ajax=1";
this.$root.overlay.frame_loading = true;
this.async_task_interval = 100;
var form = this.$refs.form;
if (form === undefined) {
form = this.$refs.formcomp.$refs.form;
}
api._postFormJSON(url, form, this.buy_callback, this.buy_error_callback);
}
},
buy_error_callback: function (xhr, data) {
if (xhr.status === 405 && typeof xhr.responseURL !== "undefined") {
// Likely a redirect!
this.$root.target_url = xhr.responseURL.substr(0, xhr.responseURL.indexOf("/cart/add") - 18);
this.$root.overlay.frame_loading = false;
this.buy();
return;
}
this.$root.overlay.error_message = strings['cart_error'];
this.$root.overlay.frame_loading = false;
},
buy_check_error_callback: function (xhr, data) {
if (xhr.status == 200 || (xhr.status >= 400 && xhr.status < 500)) {
this.$root.overlay.error_message = strings['cart_error'];
this.$root.overlay.frame_loading = false;
} else {
this.async_task_timeout = window.setTimeout(this.buy_check, 1000);
}
},
buy_callback: function (data) {
if (data.redirect) {
var iframe = this.$root.overlay.$children[0].$refs['frame-container'].children[0];
if (data.cart_id) {
this.$root.cart_id = data.cart_id;
setCookie(this.$root.cookieName, data.cart_id, 30);
}
if (data.redirect.substr(0, 1) === '/') {
data.redirect = this.$root.target_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.redirect;
}
var url = data.redirect;
if (url.indexOf('?')) {
url = url + '&iframe=1&locale=' + lang + '&take_cart_id=' + this.$root.cart_id;
} else {
url = url + '?iframe=1&locale=' + lang + '&take_cart_id=' + this.$root.cart_id;
}
if (data.success === false) {
url = url.replace(/checkout\/start/g, "");
this.$root.overlay.error_message = data.message;
if (data.has_cart) {
this.$root.overlay.error_url_after = url;
}
this.$root.overlay.frame_loading = false;
} else {
iframe.src = url;
}
} else {
this.async_task_id = data.async_id;
if (data.check_url) {
this.async_task_check_url = this.$root.target_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.check_url;
}
this.async_task_timeout = window.setTimeout(this.buy_check, this.async_task_interval);
this.async_task_interval = 250;
}
},
buy_check: function () {
api._getJSON(this.async_task_check_url, this.buy_callback, this.buy_check_error_callback);
},
redeem: function (event) {
if (this.$root.useIframe) {
event.preventDefault();
} else {
return;
}
var redirect_url = this.$root.voucherFormTarget + '&voucher=' + this.voucher + '&subevent=' + this.$root.subevent;
if (this.$root.widget_data) {
redirect_url += '&widget_data=' + escape(this.$root.widget_data_json);
}
var iframe = this.$root.overlay.$children[0].$refs['frame-container'].children[0];
this.$root.overlay.frame_loading = true;
iframe.src = redirect_url;
},
voucher_open: function (voucher) {
var redirect_url;
redirect_url = this.$root.voucherFormTarget + '&voucher=' + voucher;
if (this.$root.widget_data) {
redirect_url += '&widget_data=' + escape(this.$root.widget_data_json);
}
if (this.$root.useIframe) {
var iframe = this.$root.overlay.$children[0].$refs['frame-container'].children[0];
this.$root.overlay.frame_loading = true;
iframe.src = redirect_url;
} else {
window.open(redirect_url);
}
},
resume: function () {
var redirect_url;
redirect_url = this.$root.target_url + 'w/' + widget_id + '/?iframe=1&locale=' + lang;
if (this.$root.cart_id) {
redirect_url += '&take_cart_id=' + this.$root.cart_id;
}
if (this.$root.widget_data) {
redirect_url += '&widget_data=' + escape(this.$root.widget_data_json);
}
if (this.$root.useIframe) {
var iframe = this.$root.overlay.$children[0].$refs['frame-container'].children[0];
this.$root.overlay.frame_loading = true;
iframe.src = redirect_url;
} else {
window.open(redirect_url);
}
},
handleResize: function () {
this.mobile = this.$refs.wrapper.clientWidth <= 800;
}
};
var shared_widget_data = function () {
return {
async_task_id: null,
async_task_check_url: null,
async_task_timeout: null,
async_task_interval: 100,
voucher: null,
mobile: false,
}
};
var shared_loading_fragment = (
''
);
var shared_iframe_fragment = (
''
);
var shared_alert_fragment = (
''
+ '
'
+ ''
+ ''
+ '
'
+ '
'
);
Vue.component('pretix-overlay', {
template: (''
+ shared_iframe_fragment
+ shared_alert_fragment
+ '
'
),
computed: {
frameClasses: function () {
return {
'pretix-widget-frame-holder': true,
'pretix-widget-frame-shown': this.$root.frame_shown || this.$root.frame_loading,
};
},
alertClasses: function () {
return {
'pretix-widget-alert-holder': true,
'pretix-widget-alert-shown': this.$root.error_message,
};
},
},
methods: {
errorClose: function () {
this.$root.error_message = null;
this.$root.error_url_after = null;
},
errorContinue: function () {
var iframe = this.$refs['frame-container'].children[0];
iframe.src = this.$root.error_url_after;
this.$root.frame_loading = true;
this.$root.error_message = null;
this.$root.error_url_after = null;
},
close: function () {
this.$root.frame_shown = false;
this.$root.parent.frame_dismissed = true;
this.$root.parent.reload();
},
iframeLoaded: function () {
if (this.$root.frame_loading) {
this.$root.frame_loading = false;
this.$root.frame_shown = true;
}
}
}
});
Vue.component('pretix-widget-event-form', {
template: (''
),
computed: {
buy_label: function () {
var i, j, k, all_free = true;
for (i = 0; i < this.$root.categories.length; i++) {
var cat = this.$root.categories[i];
for (j = 0; j < cat.items.length; j++) {
var item = cat.items[j];
for (k = 0; k < item.variations.length; k++) {
var v = item.variations[k];
if (v.price.gross !== "0.00") {
all_free = false;
break;
}
}
if (item.variations.length === 0 && item.price.gross !== "0.00") {
all_free = false;
break;
}
}
if (!all_free) {
break;
}
}
if (all_free) {
return strings.register;
} else {
return strings.buy;
}
}
},
methods: {
back_to_list: function() {
this.$root.target_url = this.$root.parent_stack.pop();
this.$root.error = null;
this.$root.subevent = null;
this.$root.trigger_load_callback();
if (this.$root.events !== undefined) {
this.$root.view = "events";
} else {
this.$root.view = "weeks";
}
}
}
});
Vue.component('pretix-widget-event-list-entry', {
template: (''
+ '{{ event.name }}
'
+ '{{ event.date_range }}
'
+ '{{ location }}
' // hidden by css for now, but
// used by a few people
+ '{{ event.availability.text }}
'
+ ''),
props: {
event: Object
},
computed: {
classObject: function () {
var o = {
'pretix-widget-event-list-entry': true
};
o['pretix-widget-event-availability-' + this.event.availability.color] = true;
return o
},
location: function () {
return this.event.location.replace(/\s*\n\s*/g, ', ');
}
},
methods: {
select: function () {
this.$root.parent_stack.push(this.$root.target_url);
this.$root.target_url = this.event.event_url;
this.$root.error = null;
this.$root.subevent = this.event.subevent;
this.$root.loading++;
this.$root.reload();
}
}
});
Vue.component('pretix-widget-event-list', {
template: (''),
methods: {
back_to_calendar: function () {
if (this.$root.weeks) {
this.$root.events = undefined;
this.$root.view = "weeks";
} else {
this.$root.loading++;
this.$root.target_url = this.$root.parent_stack.pop();
this.$root.error = null;
this.$root.reload();
}
},
}
});
Vue.component('pretix-widget-event-calendar-event', {
template: (''
+ ''
+ '{{ event.name }}'
+ ''
+ '{{ event.time }}
'
+ '{{ event.availability.text }}
'
+ ''),
props: {
event: Object
},
computed: {
classObject: function () {
var o = {
'pretix-widget-event-calendar-event': true
};
o['pretix-widget-event-availability-' + this.event.availability.color] = true;
return o
}
},
methods: {
select: function () {
this.$root.parent_stack.push(this.$root.target_url);
this.$root.target_url = this.event.event_url;
this.$root.error = null;
this.$root.subevent = this.event.subevent;
this.$root.loading++;
this.$root.reload();
}
}
});
Vue.component('pretix-widget-event-calendar-cell', {
template: (''
+ ' '
+ '{{ daynum }}'
+ ' '
+ ''
+ ' | '),
props: {
day: Object
},
methods: {
selectDay: function () {
if (!this.day || !this.day.events.length || !this.$parent.$parent.$parent.mobile) {
return;
}
if (this.day.events.length === 1) {
var ev = this.day.events[0];
this.$root.parent_stack.push(this.$root.target_url);
this.$root.target_url = ev.event_url;
this.$root.error = null;
this.$root.subevent = ev.subevent;
this.$root.loading++;
this.$root.reload();
} else {
this.$root.events = this.day.events;
this.$root.view = "events";
}
}
},
computed: {
daynum: function () {
if (!this.day) {
return;
}
return this.day.date.substr(8);
},
classObject: function () {
var o = {};
if (this.day && this.day.events.length > 0) {
o['pretix-widget-has-events'] = true;
var best = 'red';
for (var i = 0; i < this.day.events.length; i++) {
var ev = this.day.events[i];
if (ev.availability.color === 'green') {
best = 'green';
} else if (ev.availability.color === 'orange' && best !== 'green') {
best = 'orange'
}
}
o['pretix-widget-day-availability-' + best] = true;
}
return o
}
}
});
Vue.component('pretix-widget-event-calendar-row', {
template: (''
+ ''
+ '
'),
props: {
week: Array
},
});
Vue.component('pretix-widget-event-calendar', {
template: (''),
computed: {
monthname: function () {
return strings['months'][this.$root.date.substr(5, 2)] + ' ' + this.$root.date.substr(0, 4);
}
},
methods: {
back_to_list: function () {
this.$root.weeks = undefined;
this.$root.view = "events";
},
prevmonth: function () {
var curMonth = parseInt(this.$root.date.substr(5, 2));
var curYear = parseInt(this.$root.date.substr(0, 4));
curMonth--;
if (curMonth < 1) {
curMonth = 12;
curYear--;
}
this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01";
this.$root.loading++;
this.$root.reload();
},
nextmonth: function () {
var curMonth = parseInt(this.$root.date.substr(5, 2));
var curYear = parseInt(this.$root.date.substr(0, 4));
curMonth++;
if (curMonth > 12) {
curMonth = 1;
curYear++;
}
this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01";
this.$root.loading++;
this.$root.reload();
}
},
});
Vue.component('pretix-widget', {
template: (''
+ ''
),
data: shared_widget_data,
methods: shared_methods,
mounted: function () {
this.mobile = this.$refs.wrapper.clientWidth <= 800;
},
computed: {
classObject: function () {
o = {'pretix-widget': true};
if (this.mobile) {
o['pretix-widget-mobile'] = true;
}
return o;
}
}
});
Vue.component('pretix-button', {
template: (''
+ ''
),
data: shared_widget_data,
methods: shared_methods,
});
/* Function to create the actual Vue instances */
var shared_root_methods = {
open_link_in_frame: function (event) {
if (this.$root.useIframe) {
event.preventDefault();
var url = event.target.attributes.href.value;
if (url.indexOf('?')) {
url += '&iframe=1';
} else {
url += '?iframe=1';
}
this.$root.overlay.$children[0].$refs['frame-container'].children[0].src = url;
this.$root.overlay.frame_loading = true;
} else {
return;
}
},
trigger_load_callback: function () {
this.$nextTick(function () {
for (var i = 0; i < window.PretixWidget._loaded.length; i++) {
window.PretixWidget._loaded[i]()
}
});
},
reload: function () {
var url;
if (this.$root.is_button) {
return;
}
if (this.$root.subevent) {
url = this.$root.target_url + this.$root.subevent + '/widget/product_list?lang=' + lang;
} else {
url = this.$root.target_url + 'widget/product_list?lang=' + lang;
}
if (this.$root.filter) {
url += '&' + this.$root.filter;
}
if (this.$root.item_filter) {
url += '&items=' + escape(this.$root.item_filter);
}
if (this.$root.category_filter) {
url += '&categories=' + escape(this.$root.category_filter);
}
var cart_id = getCookie(this.cookieName);
if (this.$root.voucher_code) {
url += '&voucher=' + escape(this.$root.voucher_code);
}
if (cart_id) {
url += "&cart_id=" + cart_id;
}
if (this.$root.date !== null) {
url += "&year=" + this.$root.date.substr(0, 4) + "&month=" + this.$root.date.substr(5, 2);
}
if (this.$root.style !== null) {
url = url + '&style=' + this.$root.style;
}
var root = this.$root;
api._getJSON(url, function (data, xhr) {
if (typeof xhr.responseURL !== "undefined" && xhr.responseURL !== url) {
var new_url = xhr.responseURL.substr(0, xhr.responseURL.indexOf("/widget/product_list?") + 1);
if (root.subevent) {
new_url = new_url.substr(0, new_url.lastIndexOf("/", new_url.length - 1) + 1);
}
root.target_url = new_url;
root.reload();
return;
}
if (data.weeks !== undefined) {
root.weeks = data.weeks;
root.date = data.date;
root.events = undefined;
root.view = "weeks";
} else if (data.events !== undefined) {
root.events = data.events;
root.weeks = undefined;
root.view = "events";
} else {
root.view = "event";
root.name = data.name;
root.categories = data.items_by_category;
root.currency = data.currency;
root.display_net_prices = data.display_net_prices;
root.voucher_explanation_text = data.voucher_explanation_text;
root.error = data.error;
root.display_add_to_cart = data.display_add_to_cart;
root.waiting_list_enabled = data.waiting_list_enabled;
root.show_variations_expanded = data.show_variations_expanded;
root.cart_id = cart_id;
root.cart_exists = data.cart_exists;
root.vouchers_exist = data.vouchers_exist;
root.has_seating_plan = data.has_seating_plan;
root.itemnum = data.itemnum;
}
root.poweredby = data.poweredby;
if (root.loading > 0) {
root.loading--;
root.trigger_load_callback();
}
if (root.parent_stack.length > 0 && root.has_seating_plan && root.categories.length === 0 && !root.frame_dismissed && root.useIframe) {
// If we're on desktop and someone selects a seating-only event in a calendar, let's open it right away,
// but only if the person didn't close it before.
root.startseating()
}
}, function (error) {
root.categories = [];
root.currency = '';
root.error = strings['loading_error'];
if (root.loading > 0) {
root.loading--;
root.trigger_load_callback();
}
});
},
startseating: function () {
var redirect_url = this.$root.target_url + 'w/' + widget_id;
if (this.$root.subevent){
redirect_url += '/' + this.$root.subevent;
}
redirect_url += '/seatingframe/?iframe=1&locale=' + lang;
if (this.$root.cart_id) {
redirect_url += '&take_cart_id=' + this.$root.cart_id;
}
if (this.$root.widget_data) {
redirect_url += '&widget_data=' + escape(this.$root.widget_data_json);
}
if (this.$root.useIframe) {
var iframe = this.$root.overlay.$children[0].$refs['frame-container'].children[0];
this.$root.overlay.frame_loading = true;
iframe.src = redirect_url;
} else {
window.open(redirect_url);
}
},
choose_event: function (event) {
root.target_url = event.event_url;
this.$root.error = null;
root.subevent = event.subevent;
root.loading++;
root.reload();
}
};
var shared_root_computed = {
cookieName: function () {
return "pretix_widget_" + this.target_url.replace(/[^a-zA-Z0-9]+/g, "_");
},
voucherFormTarget: function () {
var form_target = this.target_url + 'w/' + widget_id + '/redeem?iframe=1&locale=' + lang;
var cookie = getCookie(this.cookieName);
if (cookie) {
form_target += "&take_cart_id=" + cookie;
}
if (this.subevent) {
form_target += "&subevent=" + this.subevent;
}
return form_target;
},
formMethod: function () {
if (!this.useIframe && this.is_button && this.items.length === 0) {
return 'get';
}
return 'post';
},
formTarget: function () {
if (!this.useIframe && this.is_button && this.items.length === 0) {
var target = this.target_url;
if (this.voucher_code) {
target = this.target_url + 'redeem';
}
return target;
}
var checkout_url = "/" + this.target_url.replace(/^[^\/]+:\/\/([^\/]+)\//, "") + "w/" + widget_id + "/";
if (!this.$root.cart_exists) {
checkout_url += "checkout/start";
}
var form_target = this.target_url + 'w/' + widget_id + '/cart/add?iframe=1&next=' + encodeURIComponent(checkout_url);
var cookie = getCookie(this.cookieName);
if (cookie) {
form_target += "&take_cart_id=" + cookie;
}
return form_target
},
useIframe: function () {
return Math.min(screen.width, window.innerWidth) >= 800 && (this.skip_ssl || site_is_secure());
},
showPrices: function () {
var has_priced = false;
var cnt_items = 0;
for (var i = 0; i < this.categories.length; i++) {
for (var j = 0; j < this.categories[i].items.length; j++) {
var item = this.categories[i].items[j];
if (item.has_variations) {
cnt_items += item.variations.length;
has_priced = true;
} else {
cnt_items++;
has_priced = has_priced || item.price.gross != "0.00";
}
}
}
return has_priced || cnt_items > 1;
},
widget_data_json: function () {
return JSON.stringify(this.widget_data);
}
};
var create_overlay = function (app) {
var elem = document.createElement('pretix-overlay');
document.body.appendChild(elem);
var framechild = new Vue({
el: elem,
data: function () {
return {
parent: app,
frame_loading: false,
frame_shown: false,
error_url_after: null,
error_message: null,
}
},
methods: {
}
});
app.$root.overlay = framechild;
};
function get_ga_client_id(tracking_id) {
if (typeof ga === "undefined") {
return null;
}
try {
var trackers = ga.getAll();
var i, len;
for (i = 0, len = trackers.length; i < len; i += 1) {
if (trackers[i].get('trackingId') === tracking_id) {
return trackers[i].get('clientId');
}
}
} catch (e) {
}
return null;
}
var create_widget = function (element) {
var target_url = element.attributes.event.value;
if (!target_url.match(/\/$/)) {
target_url += "/";
}
var voucher = element.attributes.voucher ? element.attributes.voucher.value : null;
var subevent = element.attributes.subevent ? element.attributes.subevent.value : null;
var style = element.attributes.style ? element.attributes.style.value : null;
var skip_ssl = element.attributes["skip-ssl-check"] ? true : false;
var disable_vouchers = element.attributes["disable-vouchers"] ? true : false;
var widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data));
var filter = element.attributes.filter ? element.attributes.filter.value : null;
var items = element.attributes.items ? element.attributes.items.value : null;
var categories = element.attributes.categories ? element.attributes.categories.value : null;
for (var i = 0; i < element.attributes.length; i++) {
var attrib = element.attributes[i];
if (attrib.name.match(/^data-.*$/)) {
widget_data[attrib.name.replace(/^data-/, '')] = attrib.value;
}
}
if (element.tagName !== "pretix-widget") {
element.innerHTML = "";
}
var app = new Vue({
el: element,
data: function () {
return {
target_url: target_url,
parent_stack: [],
subevent: subevent,
is_button: false,
categories: null,
currency: null,
name: null,
filter: filter,
item_filter: items,
category_filter: categories,
voucher_code: voucher,
display_net_prices: false,
voucher_explanation_text: null,
show_variations_expanded: false,
skip_ssl: skip_ssl,
style: style,
error: null,
weeks: null,
date: null,
frame_dismissed: false,
events: null,
view: null,
display_add_to_cart: false,
widget_data: widget_data,
loading: 1,
widget_id: 'pretix-widget-' + widget_id,
vouchers_exist: false,
disable_vouchers: disable_vouchers,
cart_exists: false,
itemcount: 0,
overlay: null,
poweredby: "",
has_seating_plan: false
}
},
created: function () {
this.reload();
},
computed: shared_root_computed,
methods: shared_root_methods
});
create_overlay(app);
return app;
};
var create_button = function (element) {
var target_url = element.attributes.event.value;
if (!target_url.match(/\/$/)) {
target_url += "/";
}
var voucher = element.attributes.voucher ? element.attributes.voucher.value : null;
var subevent = element.attributes.subevent ? element.attributes.subevent.value : null;
var raw_items = element.attributes.items ? element.attributes.items.value : "";
var skip_ssl = element.attributes["skip-ssl-check"] ? true : false;
var button_text = element.innerHTML;
var widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data));
for (var i = 0; i < element.attributes.length; i++) {
var attrib = element.attributes[i];
if (attrib.name.match(/^data-.*$/)) {
widget_data[attrib.name.replace(/^data-/, '')] = attrib.value;
}
}
if (element.tagName !== "pretix-button") {
element.innerHTML = "" + element.innerHTML + "";
}
var itemsplit = raw_items.split(",");
var items = [];
for (var i = 0; i < itemsplit.length; i++) {
if (itemsplit[i].indexOf("=") > 0 ) {
var splitthis = itemsplit[i].split("=");
items.push({'item': splitthis[0], 'count': splitthis[1]})
}
}
var app = new Vue({
el: element,
data: function () {
return {
target_url: target_url,
subevent: subevent,
is_button: true,
skip_ssl: skip_ssl,
voucher_code: voucher,
items: items,
error: null,
filter: null,
frame_dismissed: false,
widget_data: widget_data,
widget_id: 'pretix-widget-' + widget_id,
button_text: button_text
}
},
created: function () {
},
computed: shared_root_computed,
methods: shared_root_methods
});
create_overlay(app);
return app;
};
/* Find all widgets on the page and render them */
widgetlist = [];
buttonlist = [];
window.PretixWidget._loaded = [];
window.PretixWidget.addLoadListener = function (f) {
window.PretixWidget._loaded.push(f);
}
window.PretixWidget.buildWidgets = function () {
document.createElement("pretix-widget");
document.createElement("pretix-button");
docReady(function () {
var widgets = document.querySelectorAll("pretix-widget, div.pretix-widget-compat");
var wlength = widgets.length;
for (var i = 0; i < wlength; i++) {
var widget = widgets[i];
widgetlist.push(create_widget(widget));
}
var buttons = document.querySelectorAll("pretix-button, div.pretix-button-compat");
var blength = buttons.length;
for (var i = 0; i < blength; i++) {
var button = buttons[i];
buttonlist.push(create_button(button));
}
});
};
window.PretixWidget.open = function (target_url, voucher, subevent, items, widget_data, skip_ssl_check) {
if (!target_url.match(/\/$/)) {
target_url += "/";
}
var all_widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data));
if (widget_data) {
Object.keys(widget_data).forEach(function(key) { all_widget_data[key] = widget_data[key]; });
}
var root = document.createElement("div");
document.body.appendChild(root);
root.classList.add("pretix-widget-hidden");
root.innerHTML = "";
var app = new Vue({
el: root,
data: function () {
return {
target_url: target_url,
subevent: subevent || null,
is_button: true,
skip_ssl: skip_ssl_check || false,
voucher_code: voucher || null,
items: items || [],
error: null,
filter: null,
frame_dismissed: false,
widget_data: all_widget_data,
widget_id: 'pretix-widget-' + widget_id,
button_text: ""
}
},
created: function () {
},
computed: shared_root_computed,
methods: shared_root_methods
});
create_overlay(app);
app.$nextTick(function () {
if (this.$root.useIframe) {
this.$refs.btn.buy();
} else {
console.log(this.$refs.btn.$refs.form);
this.$refs.btn.$refs.form.submit();
}
})
};
if (typeof window.pretixWidgetCallback !== "undefined") {
window.pretixWidgetCallback();
}
if (window.PretixWidget.build_widgets) {
window.PretixWidget.buildWidgets();
}
/* Set a global variable for debugging. In DEBUG mode, siteglobals will be window, otherwise it will be something
unnamed. */
siteglobals.pretixwidget_debug = {
'Vue': Vue,
'widgets': widgetlist,
'buttons': buttonlist
};