From 3b62737d4c42a2844a3b401b3b3d5420b9945c53 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Thu, 22 Dec 2022 13:01:27 +0100 Subject: [PATCH] Widget: Support for inline seating plan --- doc/user/events/widget.rst | 12 +++ src/pretix/presale/views/event.py | 6 +- .../static/pretixpresale/js/widget/widget.js | 77 ++++++++++++++----- .../static/pretixpresale/scss/widget.scss | 9 +++ 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/doc/user/events/widget.rst b/doc/user/events/widget.rst index 432840fde..e101f5c61 100644 --- a/doc/user/events/widget.rst +++ b/doc/user/events/widget.rst @@ -87,6 +87,18 @@ website. If you confident to have a good reason for not using SSL, you can overr +Seating plans +------------- + +By default, events with seating plans just show a button that opens the seating plan. You can also have the seating +plan embedded into the widget directly by using:: + + + +Note that the seating plan will only be embedded if the widget has enough space (currently min. 992 pixels width, may change +in the future) and that the seating plan part of the widget can unfortunately *not* be styled with CSS like the rest of +the widget. + Always open a new tab --------------------- diff --git a/src/pretix/presale/views/event.py b/src/pretix/presale/views/event.py index 18b0658ce..9b6b1ddc5 100644 --- a/src/pretix/presale/views/event.py +++ b/src/pretix/presale/views/event.py @@ -663,11 +663,15 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView): return context -@method_decorator(allow_frame_if_namespaced, 'dispatch') @method_decorator(iframe_entry_view_wrapper, 'dispatch') class SeatingPlanView(EventViewMixin, TemplateView): template_name = "pretixpresale/event/seatingplan.html" + def dispatch(self, request, *args, **kwargs): + r = super().dispatch(request, *args, **kwargs) + r.xframe_options_exempt = True + return r + def get(self, request, *args, **kwargs): from pretix.presale.views.cart import get_or_create_cart_id diff --git a/src/pretix/static/pretixpresale/js/widget/widget.js b/src/pretix/static/pretixpresale/js/widget/widget.js index 247f09c0c..5a64bc209 100644 --- a/src/pretix/static/pretixpresale/js/widget/widget.js +++ b/src/pretix/static/pretixpresale/js/widget/widget.js @@ -141,18 +141,21 @@ var api = { }, '_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) { + var params; + if (Array.isArray(form)) { + params = form + } else { + 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('&'); + } + params = params.map(function (el) { + return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value); + }).join('&'); var xhr = api._getXHR(); xhr.open("POST", endpoint, true); @@ -522,7 +525,7 @@ Vue.component('category', { }); var shared_methods = { - buy: function (event) { + buy: function (event, data) { if (this.$root.useIframe) { if (event) { event.preventDefault(); @@ -541,7 +544,7 @@ var shared_methods = { this.$root.overlay.frame_loading = true; this.async_task_interval = 100; - var form = this.$refs.form; + var form = data === undefined ? this.$refs.form : data; if (form === undefined) { form = this.$refs.formcomp.$refs.form; } @@ -663,7 +666,7 @@ var shared_methods = { } }, handleResize: function () { - this.mobile = this.$refs.wrapper.clientWidth <= 800; + this.clientWidth = this.$refs.wrapper.clientWidth; } }; @@ -674,7 +677,7 @@ var shared_widget_data = function () { async_task_timeout: null, async_task_interval: 100, voucher: null, - mobile: false, + clientWidth: 1000, } }; @@ -811,11 +814,16 @@ Vue.component('pretix-widget-event-form', { + '' // Seating plan - + '