From 1d6e94a3f935f305480eeb7667009b2df13d365a Mon Sep 17 00:00:00 2001 From: Yakshit Date: Mon, 30 Jun 2025 12:29:15 +0530 Subject: [PATCH 1/7] Fix: Limit Default Text Placeholders to Organizer-Selected Fields (#769) --- .../templates/pretixcontrol/pdf/index.html | 48 ++++- .../static/pretixcontrol/js/ui/editor.js | 149 ++++++++++++-- test_dual_dropdown.html | 187 ++++++++++++++++++ 3 files changed, 361 insertions(+), 23 deletions(-) create mode 100644 test_dual_dropdown.html diff --git a/src/pretix/control/templates/pretixcontrol/pdf/index.html b/src/pretix/control/templates/pretixcontrol/pdf/index.html index 359b686c67..585f5bb94b 100644 --- a/src/pretix/control/templates/pretixcontrol/pdf/index.html +++ b/src/pretix/control/templates/pretixcontrol/pdf/index.html @@ -357,16 +357,53 @@

{% trans "Welcome to the PDF ticket editor!" %}

-
- + + + + + + + + + {% for varname, var in variables.items %} - + {% if 'event' in varname or 'organizer' in varname %} + + {% endif %} {% endfor %} {% for p in request.organizer.meta_properties.all %} {% endfor %} + + + +
+
+
+
+
+ + id="toolbox-user-info-other" style="display: none;">
@@ -443,5 +480,4 @@

{% trans "Welcome to the PDF ticket editor!" %}

{% endif %} {% endfor %} {% endfor %} -{% endblock %} - +{% endblock %} \ No newline at end of file diff --git a/src/pretix/static/pretixcontrol/js/ui/editor.js b/src/pretix/static/pretixcontrol/js/ui/editor.js index 048cc4bb98..b763436a70 100644 --- a/src/pretix/static/pretixcontrol/js/ui/editor.js +++ b/src/pretix/static/pretixcontrol/js/ui/editor.js @@ -267,7 +267,21 @@ var editor = { } else if (key.startsWith('meta:')) { return key.substr(5); } - return $('#toolbox-content option[value='+key+']').attr('data-sample') || ''; + + // Check event info dropdown first + var eventSample = $('#toolbox-event-info option[value='+key+']').attr('data-sample'); + if (eventSample) { + return eventSample; + } + + // Check user info dropdown + var userSample = $('#toolbox-user-info option[value='+key+']').attr('data-sample'); + if (userSample) { + return userSample; + } + + // Return empty string if not found in either dropdown + return ''; }, _load_pdf: function (dump) { @@ -330,7 +344,8 @@ var editor = { editor.fabric.on('object:modified', editor._update_toolbox_values); editor._update_toolbox(); - $("#toolbox-content-other").hide(); + $("#toolbox-event-info-other").hide(); + $("#toolbox-user-info-other").hide(); $(".add-buttons button").prop('disabled', false); if (dump) { @@ -393,7 +408,7 @@ var editor = { } $("#toolbox-position-x").val(editor._px2mm(o.left).toFixed(2)); $("#toolbox-position-y").val(editor._px2mm(bottom).toFixed(2)); - + if (o.type === "barcodearea") { $("#toolbox-squaresize").val(editor._px2mm(o.height * o.scaleY).toFixed(2)); } else if (o.type === "imagearea") { @@ -407,7 +422,6 @@ var editor = { var col = (new fabric.Color(o.fill))._source; $("#toolbox-col").val("#" + ((1 << 24) + (col[0] << 16) + (col[1] << 8) + col[2]).toString(16).slice(1)); $("#toolbox-fontsize").val(editor._px2pt(o.fontSize).toFixed(1)); - //$("#toolbox-lineheight").val(o.lineHeight); $("#toolbox-fontfamily").val(o.fontFamily); $("#toolbox").find("button[data-action=bold]").toggleClass('active', o.fontWeight === 'bold'); $("#toolbox").find("button[data-action=italic]").toggleClass('active', o.fontStyle === 'italic'); @@ -418,12 +432,44 @@ var editor = { $("#toolbox-textwidth").val(editor._px2mm(o.width).toFixed(2)); $("#toolbox-textrotation").val((o.angle || 0.0).toFixed(1)); if (o.type === "textarea") { - $("#toolbox-content").val(o.content); - $("#toolbox-content-other").toggle($("#toolbox-content").val() === "other"); - if (o.content === "other") { - $("#toolbox-content-other").val(o.text); + // Handle dual dropdown system + var eventInfoFound = false; + var userInfoFound = false; + + // Check if content matches event info options + if ($("#toolbox-event-info option[value='" + o.content + "']").length > 0) { + $("#toolbox-event-info").val(o.content); + $("#toolbox-user-info").val(""); + eventInfoFound = true; + } + // Check if content matches user info options + else if ($("#toolbox-user-info option[value='" + o.content + "']").length > 0) { + $("#toolbox-user-info").val(o.content); + $("#toolbox-event-info").val(""); + userInfoFound = true; + } + // Handle "other" case + else { + $("#toolbox-event-info").val("other"); + $("#toolbox-user-info").val(""); + eventInfoFound = true; + } + + // Toggle visibility of "other" text areas + $("#toolbox-event-info-other").toggle($("#toolbox-event-info").val() === "other"); + $("#toolbox-user-info-other").toggle($("#toolbox-user-info").val() === "other"); + + // Set "other" text area values + if ($("#toolbox-event-info").val() === "other") { + $("#toolbox-event-info-other").val(o.text); + } else { + $("#toolbox-event-info-other").val(""); + } + + if ($("#toolbox-user-info").val() === "other") { + $("#toolbox-user-info-other").val(o.text); } else { - $("#toolbox-content-other").val(""); + $("#toolbox-user-info-other").val(""); } } } @@ -492,13 +538,43 @@ var editor = { o.setWidth(editor._mm2px($("#toolbox-textwidth").val())); o.downward = $("#toolbox").find("button[data-action=downward]").is('.active'); o.rotate(parseFloat($("#toolbox-textrotation").val())); - $("#toolbox-content-other").toggle($("#toolbox-content").val() === "other"); - o.content = $("#toolbox-content").val(); - if ($("#toolbox-content").val() === "other") { - o.set('text', $("#toolbox-content-other").val()); - } else { - o.set('text', editor._get_text_sample($("#toolbox-content").val())); + + // Handle dual dropdown system + var selectedContent = ""; + var selectedText = ""; + + // Check event info dropdown + if ($("#toolbox-event-info").val()) { + selectedContent = $("#toolbox-event-info").val(); + if (selectedContent === "other") { + selectedText = $("#toolbox-event-info-other").val(); + } else { + selectedText = editor._get_text_sample(selectedContent); + } + // Clear user info selection + $("#toolbox-user-info").val(""); + $("#toolbox-user-info-other").hide().val(""); } + // Check user info dropdown + else if ($("#toolbox-user-info").val()) { + selectedContent = $("#toolbox-user-info").val(); + if (selectedContent === "other") { + selectedText = $("#toolbox-user-info-other").val(); + } else { + selectedText = editor._get_text_sample(selectedContent); + } + // Clear event info selection + $("#toolbox-event-info").val(""); + $("#toolbox-event-info-other").hide().val(""); + } + + // Toggle visibility of "other" text areas + $("#toolbox-event-info-other").toggle($("#toolbox-event-info").val() === "other"); + $("#toolbox-user-info-other").toggle($("#toolbox-user-info").val() === "other"); + + // Update object content and text + o.content = selectedContent; + o.set('text', selectedText); } o.setCoords(); @@ -545,7 +621,7 @@ var editor = { lockRotation: false, fontFamily: 'Open Sans', lineHeight: 1, - content: 'item', + content: 'event_name', // Default to event_name editable: false, fontSize: editor._pt2px(13) }); @@ -847,6 +923,7 @@ var editor = { }, 'json'); }, + // In the init function, after line 925, add these event handlers: init: function () { editor.$pdfcv = $("#pdf-canvas"); editor.pdf_url = editor.$pdfcv.attr("data-pdf-url"); @@ -934,5 +1011,43 @@ var editor = { $(function () { editor.init(); + + // Event handlers for dual dropdown system + $("#toolbox-event-info").change(function() { + if ($(this).val() === "other") { + $("#toolbox-event-info-other").show(); + } else { + $("#toolbox-event-info-other").hide(); + } + + // Clear user info selection when event info is selected + if ($(this).val()) { + $("#toolbox-user-info").val(""); + $("#toolbox-user-info-other").hide(); + } + + editor._update_values_from_toolbox(); + }); + + $("#toolbox-user-info").change(function() { + if ($(this).val() === "other") { + $("#toolbox-user-info-other").show(); + } else { + $("#toolbox-user-info-other").hide(); + } + + // Clear event info selection when user info is selected + if ($(this).val()) { + $("#toolbox-event-info").val(""); + $("#toolbox-event-info-other").hide(); + } + + editor._update_values_from_toolbox(); + }); + + // Handle changes in "other" text areas + $("#toolbox-event-info-other, #toolbox-user-info-other").on('input', function() { + editor._update_values_from_toolbox(); + }); }); -$(window).bind('load', editor._window_load_event); +$(window).bind('load', editor._window_load_event); \ No newline at end of file diff --git a/test_dual_dropdown.html b/test_dual_dropdown.html new file mode 100644 index 0000000000..d7115d78de --- /dev/null +++ b/test_dual_dropdown.html @@ -0,0 +1,187 @@ + + + + + + Badge Editor - Dual Dropdown Test + + + +

Badge Editor - Dual Dropdown System Test

+ +
+

Event Information Placeholders

+
+ + + +
+
+ +
+

User/Attendee Information Placeholders

+
+ + + +
+
+ +
+

Preview

+
+ Selected Content: None
+ Sample Text: None +
+
+ + + + \ No newline at end of file From abc5c36603dd4c7b35c0bca8fdad9eeb17a9617e Mon Sep 17 00:00:00 2001 From: yakshit savaliya Date: Mon, 30 Jun 2025 12:34:31 +0530 Subject: [PATCH 2/7] Update test_dual_dropdown.html --- test_dual_dropdown.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_dual_dropdown.html b/test_dual_dropdown.html index d7115d78de..9c63dc6c4d 100644 --- a/test_dual_dropdown.html +++ b/test_dual_dropdown.html @@ -184,4 +184,4 @@

Preview

updatePreview(); - \ No newline at end of file + From 1a2d6fc7eead0825479109369c3c22114389fcd0 Mon Sep 17 00:00:00 2001 From: yakshit savaliya Date: Mon, 30 Jun 2025 12:34:57 +0530 Subject: [PATCH 3/7] Update editor.js --- src/pretix/static/pretixcontrol/js/ui/editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pretix/static/pretixcontrol/js/ui/editor.js b/src/pretix/static/pretixcontrol/js/ui/editor.js index b763436a70..fff2e06fad 100644 --- a/src/pretix/static/pretixcontrol/js/ui/editor.js +++ b/src/pretix/static/pretixcontrol/js/ui/editor.js @@ -1050,4 +1050,4 @@ $(function () { editor._update_values_from_toolbox(); }); }); -$(window).bind('load', editor._window_load_event); \ No newline at end of file +$(window).bind('load', editor._window_load_event); From 535961d839c252670aa65ae9ca796917dc86dde3 Mon Sep 17 00:00:00 2001 From: yakshit savaliya Date: Mon, 30 Jun 2025 12:35:14 +0530 Subject: [PATCH 4/7] Update index.html --- src/pretix/control/templates/pretixcontrol/pdf/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pretix/control/templates/pretixcontrol/pdf/index.html b/src/pretix/control/templates/pretixcontrol/pdf/index.html index 585f5bb94b..2571bb13a2 100644 --- a/src/pretix/control/templates/pretixcontrol/pdf/index.html +++ b/src/pretix/control/templates/pretixcontrol/pdf/index.html @@ -480,4 +480,4 @@

{% trans "Welcome to the PDF ticket editor!" %}

{% endif %} {% endfor %} {% endfor %} -{% endblock %} \ No newline at end of file +{% endblock %} From 7f3f2a0d7eb22d2946123a2fd9ab72fca517af5f Mon Sep 17 00:00:00 2001 From: yakshit savaliya Date: Mon, 30 Jun 2025 12:52:56 +0530 Subject: [PATCH 5/7] Improved the code-quality, chaneged from "var" to let. --- .../static/pretixcontrol/js/ui/editor.js | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/src/pretix/static/pretixcontrol/js/ui/editor.js b/src/pretix/static/pretixcontrol/js/ui/editor.js index fff2e06fad..c4ccb36012 100644 --- a/src/pretix/static/pretixcontrol/js/ui/editor.js +++ b/src/pretix/static/pretixcontrol/js/ui/editor.js @@ -5,7 +5,7 @@ fabric.Poweredby = fabric.util.createClass(fabric.Image, { initialize: function (options) { options || (options = {}); - var el = $("#poweredby-" + options.content).get(0) + let el = $("#poweredby-" + options.content).get(0) this.callSuper('initialize', el, options); this.set('label', options.label || ''); }, @@ -95,7 +95,7 @@ fabric.Textarea.fromObject = function (object, callback, forceAsync) { }; -var editor = { +let editor = { $pdfcv: null, $fcv: null, $cva: null, @@ -131,20 +131,20 @@ var editor = { }, dump: function (objs) { - var d = []; + let d = []; objs = objs || editor.fabric.getObjects(); - for (var i in objs) { - var o = objs[i]; - var top = o.top; - var left = o.left; + for (let i in objs) { + let o = objs[i]; + let top = o.top; + let left = o.left; if (o.group) { top += o.group.top + o.group.height / 2; left += o.group.left + o.group.width / 2; } if (o.type === "textarea") { - var col = (new fabric.Color(o.fill))._source; - var bottom = editor.pdf_viewport.height - o.height - top; + let col = (new fabric.Color(o.fill))._source; + let bottom = editor.pdf_viewport.height - o.height - top; if (o.downward) { bottom = editor.pdf_viewport.height - top; } @@ -241,7 +241,7 @@ var editor = { } } - var new_top = editor.pdf_viewport.height - editor._mm2px(d.bottom) - (o.height * o.scaleY); + let new_top = editor.pdf_viewport.height - editor._mm2px(d.bottom) - (o.height * o.scaleY); if (o.downward) { new_top = editor.pdf_viewport.height - editor._mm2px(d.bottom); } @@ -253,8 +253,8 @@ var editor = { load: function(data) { editor.fabric.clear(); - for (var i in data) { - var d = data[i], o; + for (let i in data) { + let d = data[i], o; editor._add_from_data(d); } editor.fabric.renderAll(); @@ -269,13 +269,13 @@ var editor = { } // Check event info dropdown first - var eventSample = $('#toolbox-event-info option[value='+key+']').attr('data-sample'); + let eventSample = $('#toolbox-event-info option[value='+key+']').attr('data-sample'); if (eventSample) { return eventSample; } // Check user info dropdown - var userSample = $('#toolbox-user-info option[value='+key+']').attr('data-sample'); + let userSample = $('#toolbox-user-info option[value='+key+']').attr('data-sample'); if (userSample) { return userSample; } @@ -286,26 +286,26 @@ var editor = { _load_pdf: function (dump) { // TODO: Loading indicators - var url = editor.pdf_url; + let url = editor.pdf_url; // TODO: Handle cross-origin issues if static files are on a different origin PDFJS.workerSrc = editor.$pdfcv.attr("data-worker-url"); // Asynchronous download of PDF - var loadingTask = PDFJS.getDocument(url); + let loadingTask = PDFJS.getDocument(url); loadingTask.promise.then(function (pdf) { console.log('PDF loaded'); // Fetch the first page - var pageNumber = 1; + let pageNumber = 1; pdf.getPage(pageNumber).then(function (page) { console.log('Page loaded'); - var canvas = document.getElementById('pdf-canvas'); + let canvas = document.getElementById('pdf-canvas'); - var scale = editor.$cva.width() / page.getViewport(1.0).width; - var viewport = page.getViewport(scale); + let scale = editor.$cva.width() / page.getViewport(1.0).width; + let viewport = page.getViewport(scale); // Prepare canvas using PDF page dimensions - var context = canvas.getContext('2d'); + let context = canvas.getContext('2d'); context.clearRect(0, 0, canvas.width, canvas.height); canvas.height = viewport.height; canvas.width = viewport.width; @@ -315,18 +315,18 @@ var editor = { editor.pdf_viewport = viewport; // Render PDF page into canvas context - var renderContext = { + let renderContext = { canvasContext: context, viewport: viewport }; - var renderTask = page.render(renderContext); + let renderTask = page.render(renderContext); renderTask.then(function () { console.log('Page rendered'); editor._init_fabric(dump); }); }); }, function (reason) { - var msg = gettext('The PDF background file could not be loaded for the following reason:'); + let msg = gettext('The PDF background file could not be loaded for the following reason:'); editor._error(msg + ' ' + reason); }); }, @@ -351,7 +351,7 @@ var editor = { if (dump) { editor.load(dump); } else { - var data = $.trim($("#editor-data").text()); + let data = $.trim($("#editor-data").text()); if (data) { editor.load(JSON.parse(data)); } @@ -380,10 +380,10 @@ var editor = { }, _ready: function () { - var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; - var isFirefox = typeof InstallTrigger !== 'undefined'; - var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime); - var isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1); + let isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; + let isFirefox = typeof InstallTrigger !== 'undefined'; + let isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime); + let isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1); if (isChrome || isOpera || isFirefox || isEdgeChromium) { $("#loading-container").hide(); $("#loading-initial").remove(); @@ -398,11 +398,11 @@ var editor = { }, _update_toolbox_values: function () { - var o = editor.fabric.getActiveObject(); + let o = editor.fabric.getActiveObject(); if (!o) { return; } - var bottom = editor.pdf_viewport.height - o.height * o.scaleY - o.top; + let bottom = editor.pdf_viewport.height - o.height * o.scaleY - o.top; if (o.downward) { bottom = editor.pdf_viewport.height - o.top; } @@ -419,7 +419,7 @@ var editor = { $("#toolbox-squaresize").val(editor._px2mm(o.height * o.scaleY).toFixed(2)); $("#toolbox-poweredby-style").val(o.content); } else if (o.type === "text" || o.type === "textarea") { - var col = (new fabric.Color(o.fill))._source; + let col = (new fabric.Color(o.fill))._source; $("#toolbox-col").val("#" + ((1 << 24) + (col[0] << 16) + (col[1] << 8) + col[2]).toString(16).slice(1)); $("#toolbox-fontsize").val(editor._px2pt(o.fontSize).toFixed(1)); $("#toolbox-fontfamily").val(o.fontFamily); @@ -433,8 +433,8 @@ var editor = { $("#toolbox-textrotation").val((o.angle || 0.0).toFixed(1)); if (o.type === "textarea") { // Handle dual dropdown system - var eventInfoFound = false; - var userInfoFound = false; + let eventInfoFound = false; + let userInfoFound = false; // Check if content matches event info options if ($("#toolbox-event-info option[value='" + o.content + "']").length > 0) { @@ -476,12 +476,12 @@ var editor = { }, _update_values_from_toolbox: function () { - var o = editor.fabric.getActiveObject(); + let o = editor.fabric.getActiveObject(); if (!o) { return; } - var new_top = editor.pdf_viewport.height - editor._mm2px($("#toolbox-position-y").val()) - o.height * o.scaleY; + let new_top = editor.pdf_viewport.height - editor._mm2px($("#toolbox-position-y").val()) - o.height * o.scaleY; if (o.type === "textarea" || o.type === "text") { if ($("#toolbox").find("button[data-action=downward]").is('.active')) { new_top = editor.pdf_viewport.height - editor._mm2px($("#toolbox-position-y").val()); @@ -491,7 +491,7 @@ var editor = { o.set('top', new_top); if (o.type === "barcodearea") { - var new_h = editor._mm2px($("#toolbox-squaresize").val()); + let new_h = editor._mm2px($("#toolbox-squaresize").val()); new_top += o.height * o.scaleY - new_h; o.set('height', new_h); o.set('width', new_h); @@ -499,8 +499,8 @@ var editor = { o.set('scaleY', 1); o.set('top', new_top) } else if (o.type === "imagearea") { - var new_w = editor._mm2px($("#toolbox-width").val()); - var new_h = editor._mm2px($("#toolbox-height").val()); + let new_w = editor._mm2px($("#toolbox-width").val()); + let new_h = editor._mm2px($("#toolbox-height").val()); new_top += o.height * o.scaleY - new_h; o.set('height', new_h); o.set('width', new_w); @@ -509,7 +509,7 @@ var editor = { o.set('top', new_top) o.content = $("#toolbox-imagecontent").val(); } else if (o.type === "poweredby") { - var new_h = Math.max(1, editor._mm2px($("#toolbox-squaresize").val())); + let new_h = Math.max(1, editor._mm2px($("#toolbox-squaresize").val())); new_top += o.height * o.scaleY - new_h; o.set('width', new_h / o.height * o.width); o.set('height', new_h); @@ -517,9 +517,9 @@ var editor = { o.set('scaleY', 1); o.set('top', new_top) if ($("#toolbox-poweredby-style").val() !== o.content) { - var data = editor.dump([o]); + let data = editor.dump([o]); data[0].content = $("#toolbox-poweredby-style").val(); - var newo = editor._add_from_data(data[0]); + let newo = editor._add_from_data(data[0]); editor.fabric.remove(o); editor.fabric.discardActiveObject(); editor.fabric.setActiveObject(newo); @@ -531,7 +531,7 @@ var editor = { o.set('fontFamily', $("#toolbox-fontfamily").val()); o.set('fontWeight', $("#toolbox").find("button[data-action=bold]").is('.active') ? 'bold' : 'normal'); o.set('fontStyle', $("#toolbox").find("button[data-action=italic]").is('.active') ? 'italic' : 'normal'); - var align = $("#toolbox-align").find(".active").attr("data-action"); + let align = $("#toolbox-align").find(".active").attr("data-action"); if (align) { o.set('textAlign', align); } @@ -540,8 +540,8 @@ var editor = { o.rotate(parseFloat($("#toolbox-textrotation").val())); // Handle dual dropdown system - var selectedContent = ""; - var selectedText = ""; + let selectedContent = ""; + let selectedText = ""; // Check event info dropdown if ($("#toolbox-event-info").val()) { @@ -582,12 +582,12 @@ var editor = { }, _update_toolbox: function () { - var selected = editor.fabric.getActiveObjects(); + let selected = editor.fabric.getActiveObjects(); if (selected.length > 1) { $("#toolbox").attr("data-type", "group"); $("#toolbox-heading").text(gettext("Group of objects")); } else if (selected.length == 1) { - var o = selected[0]; + let o = selected[0]; $("#toolbox").attr("data-type", o.type); if (o.type === "textarea" || o.type === "text") { $("#toolbox-heading").text(gettext("Text object")); @@ -614,7 +614,7 @@ var editor = { }, _add_text: function () { - var text = new fabric.Textarea(editor._get_text_sample('event_name'), { + let text = new fabric.Textarea(editor._get_text_sample('event_name'), { left: 100, top: 100, width: editor._mm2px(50), @@ -643,7 +643,7 @@ var editor = { }, _add_poweredby: function (content) { - var rect = new fabric.Poweredby({ + let rect = new fabric.Poweredby({ left: 100, top: 100, height: 629, @@ -659,7 +659,7 @@ var editor = { }, _add_imagearea: function () { - var rect = new fabric.Imagearea({ + let rect = new fabric.Imagearea({ left: 100, top: 100, width: 100, @@ -675,7 +675,7 @@ var editor = { }, _add_qrcode: function () { - var rect = new fabric.Barcodearea({ + let rect = new fabric.Barcodearea({ left: 100, top: 100, width: 100, @@ -692,7 +692,7 @@ var editor = { _cut: function () { editor._history_modification_in_progress = true; - var thing = editor.fabric.getActiveObject(); + let thing = editor.fabric.getActiveObject(); if (thing.type === "activeSelection") { editor.clipboard = editor.dump(thing._objects); thing.forEachObject(function (o) { @@ -710,7 +710,7 @@ var editor = { _copy: function () { editor._history_modification_in_progress = true; - var thing = editor.fabric.getActiveObject(); + let thing = editor.fabric.getActiveObject(); if (thing.type === "activeSelection") { editor.clipboard = editor.dump(thing._objects); } else { @@ -725,13 +725,13 @@ var editor = { return; } editor._history_modification_in_progress = true; - var objs = []; - for (var i in editor.clipboard) { + let objs = []; + for (let i in editor.clipboard) { objs.push(editor._add_from_data(editor.clipboard[i])); } editor.fabric.discardActiveObject(); if (editor.clipboard.length > 1) { - var selection = new fabric.ActiveSelection(objs, {canvas: editor.fabric}); + let selection = new fabric.ActiveSelection(objs, {canvas: editor.fabric}); editor.fabric.setActiveObject(selection); } else { editor.fabric.setActiveObject(objs[0]); @@ -741,7 +741,7 @@ var editor = { }, _delete: function () { - var thing = editor.fabric.getActiveObject(); + let thing = editor.fabric.getActiveObject(); if (thing.type === "activeSelection") { thing.forEachObject(function (o) { editor.fabric.remove(o); @@ -756,8 +756,8 @@ var editor = { }, _on_keydown: function (e) { - var step = e.shiftKey ? editor._mm2px(10) : editor._mm2px(1); - var thing = editor.fabric.getActiveObject(); + let step = e.shiftKey ? editor._mm2px(10) : editor._mm2px(1); + let thing = editor.fabric.getActiveObject(); if ($("#source-container").is(':visible')) { return true; } @@ -822,7 +822,7 @@ var editor = { if (editor._history_modification_in_progress) { return; } - var state = editor.dump(); + let state = editor.dump(); if (editor._history_pos > 0) { editor.history.splice(-1 * editor._history_pos, editor._history_pos); editor._history_pos = 0; @@ -854,7 +854,7 @@ var editor = { _save: function () { $("#editor-save").prop('disabled', true).prepend(''); - var dump = editor.dump(); + let dump = editor.dump(); $.post(window.location.href, { 'data': JSON.stringify(dump), 'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val(), @@ -975,7 +975,7 @@ var editor = { }); }, progressall: function (e, data) { - var progress = parseInt(data.loaded / data.total * 100, 10); + let progress = parseInt(data.loaded / data.total * 100, 10); $('#loading-upload .progress-bar').css('width', progress + '%'); } }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled'); From eeba2817a9255080279da3e94dceea8ea6f386fb Mon Sep 17 00:00:00 2001 From: yakshit savaliya Date: Mon, 30 Jun 2025 18:35:21 +0530 Subject: [PATCH 6/7] Rename test_dual_dropdown.html to src/tests/plugins/badges/test_dual_dropdown.html --- .../tests/plugins/badges/test_dual_dropdown.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test_dual_dropdown.html => src/tests/plugins/badges/test_dual_dropdown.html (100%) diff --git a/test_dual_dropdown.html b/src/tests/plugins/badges/test_dual_dropdown.html similarity index 100% rename from test_dual_dropdown.html rename to src/tests/plugins/badges/test_dual_dropdown.html From 101250c5d90849d93a43f97f2624801f45d7b579 Mon Sep 17 00:00:00 2001 From: yakshit savaliya Date: Mon, 30 Jun 2025 18:50:40 +0530 Subject: [PATCH 7/7] updates as per the reviews I have Reduced Duplicated Logic, Organized Event Handler Attachments --- .../static/pretixcontrol/js/ui/editor.js | 96 +++++++++++-------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/src/pretix/static/pretixcontrol/js/ui/editor.js b/src/pretix/static/pretixcontrol/js/ui/editor.js index c4ccb36012..f95371d7c5 100644 --- a/src/pretix/static/pretixcontrol/js/ui/editor.js +++ b/src/pretix/static/pretixcontrol/js/ui/editor.js @@ -130,6 +130,61 @@ let editor = { return v * editor.pdf_scale / editor.pdf_page.userUnit; }, + // Helper functions for dual dropdown system + _toggleOtherTextArea: function(dropdownId, otherTextAreaId) { + const dropdown = $("#" + dropdownId); + const otherTextArea = $("#" + otherTextAreaId); + + if (dropdown.val() === "other") { + otherTextArea.show(); + } else { + otherTextArea.hide(); + } + }, + + _clearOppositeDropdown: function(activeDropdownId, oppositeDropdownId, oppositeOtherTextAreaId) { + const activeDropdown = $("#" + activeDropdownId); + const oppositeDropdown = $("#" + oppositeDropdownId); + const oppositeOtherTextArea = $("#" + oppositeOtherTextAreaId); + + if (activeDropdown.val()) { + oppositeDropdown.val(""); + oppositeOtherTextArea.hide(); + } + }, + + _handleDropdownChange: function(dropdownId, otherTextAreaId, oppositeDropdownId, oppositeOtherTextAreaId) { + editor._toggleOtherTextArea(dropdownId, otherTextAreaId); + editor._clearOppositeDropdown(dropdownId, oppositeDropdownId, oppositeOtherTextAreaId); + editor._update_values_from_toolbox(); + }, + + _bindDualDropdownEvents: function() { + // Event handlers for dual dropdown system + $("#toolbox-event-info").change(function() { + editor._handleDropdownChange( + "toolbox-event-info", + "toolbox-event-info-other", + "toolbox-user-info", + "toolbox-user-info-other" + ); + }); + + $("#toolbox-user-info").change(function() { + editor._handleDropdownChange( + "toolbox-user-info", + "toolbox-user-info-other", + "toolbox-event-info", + "toolbox-event-info-other" + ); + }); + + // Handle changes in "other" text areas + $("#toolbox-event-info-other, #toolbox-user-info-other").on('input', function() { + editor._update_values_from_toolbox(); + }); + }, + dump: function (objs) { let d = []; objs = objs || editor.fabric.getObjects(); @@ -1006,48 +1061,13 @@ let editor = { $("#toolbox-source").bind('click', editor._source_show); $("#source-close").bind('click', editor._source_close); $("#source-save").bind('click', editor._source_save); + + // Initialize dual dropdown events + editor._bindDualDropdownEvents(); } }; $(function () { editor.init(); - - // Event handlers for dual dropdown system - $("#toolbox-event-info").change(function() { - if ($(this).val() === "other") { - $("#toolbox-event-info-other").show(); - } else { - $("#toolbox-event-info-other").hide(); - } - - // Clear user info selection when event info is selected - if ($(this).val()) { - $("#toolbox-user-info").val(""); - $("#toolbox-user-info-other").hide(); - } - - editor._update_values_from_toolbox(); - }); - - $("#toolbox-user-info").change(function() { - if ($(this).val() === "other") { - $("#toolbox-user-info-other").show(); - } else { - $("#toolbox-user-info-other").hide(); - } - - // Clear event info selection when user info is selected - if ($(this).val()) { - $("#toolbox-event-info").val(""); - $("#toolbox-event-info-other").hide(); - } - - editor._update_values_from_toolbox(); - }); - - // Handle changes in "other" text areas - $("#toolbox-event-info-other, #toolbox-user-info-other").on('input', function() { - editor._update_values_from_toolbox(); - }); }); $(window).bind('load', editor._window_load_event);