From 81245cf12569ab6e05c6de5151d4d2301e04d513 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Sat, 1 Feb 2020 15:59:24 +0100 Subject: [PATCH] Fix #1549 -- JS API to open pretix Button --- doc/user/events/widget.rst | 25 +++++++++- .../static/pretixpresale/js/widget/widget.js | 48 +++++++++++++++++++ .../static/pretixpresale/scss/widget.scss | 3 ++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/doc/user/events/widget.rst b/doc/user/events/widget.rst index fe03a05f8..f4ce80908 100644 --- a/doc/user/events/widget.rst +++ b/doc/user/events/widget.rst @@ -183,6 +183,24 @@ Just as the widget, the button supports the optional attributes ``voucher`` and You can style the button using the ``pretix-button`` CSS class. +Dynamically opening the widget +------------------------------ + +You can get the behaviour of the pretix Button without a button at all, so you can trigger it from your own code in +response to a user action. Usually, this will open an overlay with your ticket shop, however in some cases, such as +missing HTTPS encryption on your case or a really small screen (mobile), it will open a new tab instead of an overlay. +Therefore, make sure you call this *in direct response to a user action*, otherwise most browser will block it as an +unwanted popup. + +.. js:function:: window.PretixWidget.open(target_url [, voucher [, subevent [, items, [, widget_data [, skip_ssl_check ]]]]]) + + :param string target_url: The URL of the ticket shop. + :param string voucher: A voucher code to be pre-selected, or ``null``. + :param string subevent: A subevent to be pre-selected, or ``null``. + :param array items: A collection of items to be put in the cart, of the form ``[{"item": "item_3", "count": 1}, {"item": "variation_5_6", "count": 4}]`` + :param object widget_data: Additional data to be passed to the shop, see below. + :param boolean skip_ssl_check: Whether to ignore the check for HTTPS. Only to be used during development. + Dynamically loading the widget ------------------------------ @@ -238,7 +256,8 @@ with that information:: data-question-L9G8NG9M="Foobar"> -This works for the pretix Button as well. Currently, the following attributes are understood by pretix itself: +This works for the pretix Button as well, if you also specify a product. +Currently, the following attributes are understood by pretix itself: * ``data-email`` will pre-fill the order email field as well as the attendee email field (if enabled). @@ -303,4 +322,8 @@ Hosted or pretix Enterprise are active, you can pass the following fields: Data passing options have been added in pretix 2.3. If you use a self-hosted version of pretix, they only work fully if you configured a redis server. +.. versionchanged:: 3.6 + + Dynamically opening the widget has been added in pretix 3.6. + .. _Let's Encrypt: https://letsencrypt.org/ diff --git a/src/pretix/static/pretixpresale/js/widget/widget.js b/src/pretix/static/pretixpresale/js/widget/widget.js index 843e53384..4662b7104 100644 --- a/src/pretix/static/pretixpresale/js/widget/widget.js +++ b/src/pretix/static/pretixpresale/js/widget/widget.js @@ -1448,6 +1448,54 @@ window.PretixWidget.buildWidgets = function () { } }); }; + +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(); } diff --git a/src/pretix/static/pretixpresale/scss/widget.scss b/src/pretix/static/pretixpresale/scss/widget.scss index 9b98f024d..4ef6f7f2e 100644 --- a/src/pretix/static/pretixpresale/scss/widget.scss +++ b/src/pretix/static/pretixpresale/scss/widget.scss @@ -2,6 +2,9 @@ @import "../../bootstrap/scss/bootstrap/variables"; @import "../../bootstrap/scss/bootstrap/mixins"; +.pretix-widget-hidden { + display: none; +} .pretix-widget, .pretix-widget-alert-box { a { color: $link-color;