/*global $,gettext*/ function gettext(msgid) { if (typeof django !== 'undefined' && typeof django.gettext !== 'undefined') { return django.gettext(msgid); } return msgid; } function ngettext(singular, plural, count) { if (typeof django !== 'undefined' && typeof django.ngettext !== 'undefined') { return django.ngettext(singular, plural, count); } return plural; } var waitingDialog = { show: function (message) { "use strict"; $("#loadingmodal").find("h1").html(message); $("body").addClass("loading"); }, hide: function () { "use strict"; $("body").removeClass("loading"); } }; var ajaxErrDialog = { show: function (c) { "use strict"; $("#ajaxerr").html(c); $("#ajaxerr .links").html("" + gettext("Close message") + ""); $("body").addClass("ajaxerr"); }, hide: function () { "use strict"; $("body").removeClass("ajaxerr"); } }; var apiGET = function (url, callback) { $.getJSON(url, function (data) { callback(data); }); }; var i18nToString = function (i18nstring) { var locale = $("body").attr("data-pretixlocale"); if (i18nstring[locale]) { return i18nstring[locale]; } else if (i18nstring["en"]) { return i18nstring["en"]; } for (key in i18nstring) { if (i18nstring[key]) { return i18nstring[key]; } } }; $(document).ajaxError(function (event, jqXHR, settings, thrownError) { waitingDialog.hide(); var c = $(jqXHR.responseText).filter('.container'); if (c.length > 0) { ajaxErrDialog.show(c.first().html()); } else if (thrownError !== "abort" && thrownError !== "") { console.log(thrownError); alert(gettext('Unknown error.')); } }); var form_handlers = function (el) { el.find(".datetimepicker").each(function () { $(this).datetimepicker({ format: $("body").attr("data-datetimeformat"), locale: $("body").attr("data-datetimelocale"), useCurrent: false, showClear: !$(this).prop("required"), icons: { time: 'fa fa-clock-o', date: 'fa fa-calendar', up: 'fa fa-chevron-up', down: 'fa fa-chevron-down', previous: 'fa fa-chevron-left', next: 'fa fa-chevron-right', today: 'fa fa-screenshot', clear: 'fa fa-trash', close: 'fa fa-remove' } }); if (!$(this).val()) { $(this).data("DateTimePicker").viewDate(moment().hour(0).minute(0).second(0)); } }); el.find(".datepickerfield").each(function () { var opts = { format: $("body").attr("data-dateformat"), locale: $("body").attr("data-datetimelocale"), useCurrent: false, showClear: !$(this).prop("required"), icons: { time: 'fa fa-clock-o', date: 'fa fa-calendar', up: 'fa fa-chevron-up', down: 'fa fa-chevron-down', previous: 'fa fa-chevron-left', next: 'fa fa-chevron-right', today: 'fa fa-screenshot', clear: 'fa fa-trash', close: 'fa fa-remove' }, }; if ($(this).is('[data-min]')) { opts["minDate"] = $(this).attr("data-min"); opts["viewDate"] = $(this).attr("data-min"); } if ($(this).is('[data-max]')) { opts["maxDate"] = $(this).attr("data-max"); opts["viewDate"] = $(this).attr("data-max"); } if ($(this).is('[data-is-payment-date]')) opts["daysOfWeekDisabled"] = JSON.parse($("body").attr("data-payment-weekdays-disabled")); $(this).datetimepicker(opts); if ($(this).parent().is('.splitdatetimerow')) { $(this).on("dp.change", function (ev) { var $timepicker = $(this).closest(".splitdatetimerow").find(".timepickerfield"); var date = $(this).data('DateTimePicker').date(); if (date === null) { return; } if ($timepicker.val() === "") { date.set({'hour': 0, 'minute': 0, 'second': 0}); $timepicker.data('DateTimePicker').date(date); } }); } }); el.find(".timepickerfield").each(function () { var opts = { format: $("body").attr("data-timeformat"), locale: $("body").attr("data-datetimelocale"), useCurrent: false, showClear: !$(this).prop("required"), icons: { time: 'fa fa-clock-o', date: 'fa fa-calendar', up: 'fa fa-chevron-up', down: 'fa fa-chevron-down', previous: 'fa fa-chevron-left', next: 'fa fa-chevron-right', today: 'fa fa-screenshot', clear: 'fa fa-trash', close: 'fa fa-remove' } }; if ($(this).is('[data-is-payment-date]')) opts["daysOfWeekDisabled"] = JSON.parse($("body").attr("data-payment-weekdays-disabled")); $(this).datetimepicker(opts); }); el.find(".datetimepicker[data-date-after], .datepickerfield[data-date-after]").each(function () { var later_field = $(this), earlier_field = $($(this).attr("data-date-after")), update = function () { var earlier = earlier_field.data('DateTimePicker').date(), later = later_field.data('DateTimePicker').date(); if (earlier === null) { earlier = false; } else if (later !== null && later.isBefore(earlier) && !later.isSame(earlier)) { later_field.data('DateTimePicker').date(earlier.add(1, 'h')); } later_field.data('DateTimePicker').minDate(earlier); }; update(); earlier_field.on("dp.change", update); }); el.find(".datetimepicker[data-date-default], .datepickerfield[data-date-default]").each(function () { var fill_field = $(this), default_field = $($(this).attr("data-date-default")), show = function () { var fill_date = fill_field.data('DateTimePicker').date(), default_date = default_field.data('DateTimePicker').date(); if (fill_date === null) { fill_field.data("DateTimePicker").defaultDate(default_date); } }; fill_field.on("dp.show", show); }); function luminanace(r, g, b) { var a = [r, g, b].map(function (v) { v /= 255; return v <= 0.03928 ? v / 12.92 : Math.pow( (v + 0.055) / 1.055, 2.4 ); }); return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; } function contrast(rgb1, rgb2) { var l1 = luminanace(rgb1[0], rgb1[1], rgb1[2]) + 0.05, l2 = luminanace(rgb2[0], rgb2[1], rgb2[2]) + 0.05, ratio = l1/l2 if (l2 > l1) {ratio = 1/ratio} return ratio.toFixed(1) } el.find(".colorpickerfield").colorpicker({ format: 'hex', align: 'left', customClass: 'colorpicker-2x', sliders: { saturation: { maxLeft: 200, maxTop: 200 }, hue: { maxTop: 200 }, alpha: { maxTop: 200 } } }).on('changeColor create', function (e) { var rgb = $(this).colorpicker('color').toRGB(); var c = contrast([255,255,255], [rgb.r, rgb.g, rgb.b]); var mark = 'times'; if ($(this).parent().find(".contrast-state").length === 0) { $(this).parent().append("
"); } var $note = $(this).parent().find(".contrast-state"); if ($(this).val() === "") { $note.remove(); } if (!$(this).is(".no-contrast")) { if (c > 7) { $note.html("") .append(gettext('Your color has great contrast and is very easy to read!')); $note.addClass("text-success").removeClass("text-warning").removeClass("text-danger"); } else if (c > 2.5) { $note.html("") .append(gettext('Your color has decent contrast and is probably good-enough to read!')); $note.removeClass("text-success").removeClass("text-warning").removeClass("text-danger"); } else { $note.html("") .append(gettext('Your color has bad contrast for text on white background, please choose a darker ' + 'shade.')); $note.addClass("text-danger").removeClass("text-success").removeClass("text-warning"); } } }); el.find("input[data-checkbox-dependency]").each(function () { var dependent = $(this), dependency = $($(this).attr("data-checkbox-dependency")), update = function () { var enabled = dependency.prop('checked'); dependent.prop('disabled', !enabled).closest('.form-group, .form-field-boundary').toggleClass('disabled', !enabled); if (!enabled && !$(this).is('[data-checkbox-dependency-visual]')) { dependent.prop('checked', false); } }; update(); dependency.on("change", update); }); el.find("select[data-inverse-dependency], input[data-inverse-dependency]").each(function () { var dependency = $(this).attr("data-inverse-dependency"); if (dependency.substr(0, 1) === '<') { dependency = $(this).closest("form, .form-horizontal").find(dependency.substr(1)); } else { dependency = $(dependency); } var dependent = $(this), update = function () { var enabled = !dependency.prop('checked'); dependent.prop('disabled', !enabled).closest('.form-group, .form-field-boundary').toggleClass('disabled', !enabled); }; update(); dependency.on("change", update); }); el.find("div[data-display-dependency], textarea[data-display-dependency], input[data-display-dependency], select[data-display-dependency]").each(function () { var dependent = $(this), dependency = $($(this).attr("data-display-dependency")), update = function (ev) { var enabled = (dependency.attr("type") === 'checkbox' || dependency.attr("type") === 'radio') ? dependency.prop('checked') : !!dependency.val(); var $toggling = dependent; if (dependent.get(0).tagName.toLowerCase() !== "div") { $toggling = dependent.closest('.form-group'); } if (ev) { if (enabled) { $toggling.stop().slideDown(); } else { $toggling.stop().slideUp(); } } else { $toggling.stop().toggle(enabled); } }; update(); dependency.closest('.form-group').find('input[name=' + dependency.attr("name") + ']').on("change", update); dependency.closest('.form-group').find('input[name=' + dependency.attr("name") + ']').on("dp.change", update); }); el.find("input[data-required-if], select[data-required-if], textarea[data-required-if]").each(function () { var dependent = $(this), dependency = $($(this).attr("data-required-if")), update = function (ev) { var enabled = (dependency.attr("type") === 'checkbox' || dependency.attr("type") === 'radio') ? dependency.prop('checked') : !!dependency.val(); dependent.prop('required', enabled).closest('.form-group').toggleClass('required', enabled).find('.optional').stop().animate({ 'opacity': enabled ? 0 : 1 }, ev ? 500 : 1); }; update(); dependency.closest('.form-group').find('input[name=' + dependency.attr("name") + ']').on("change", update); dependency.closest('.form-group').find('input[name=' + dependency.attr("name") + ']').on("dp.change", update); }); $("input[name$=vat_id][data-countries-in-eu]").each(function () { var dependent = $(this), dependency_country = $(this).closest(".panel-body, form").find('select[name$=country]'), dependency_id_is_business_1 = $(this).closest(".panel-body, form").find('input[id$=id_is_business_1]'), update = function (ev) { if (dependency_id_is_business_1.length && !dependency_id_is_business_1.prop("checked")) { dependent.closest(".form-group").hide(); } else if (dependent.attr('data-countries-in-eu').split(',').includes(dependency_country.val())) { dependent.closest(".form-group").show(); } else { dependent.closest(".form-group").hide(); } }; update(); dependency_country.on("change", update); dependency_id_is_business_1.on("change", update); }); $("select[name$=state]:not([data-static])").each(function () { var dependent = $(this), counter = 0, dependency = $(this).closest("form").find('select[name$=country]'), update = function (ev) { counter++; var curCounter = counter; dependent.prop("disabled", true); dependency.closest(".form-group").find("label").prepend(" "); $.getJSON('/js_helpers/states/?country=' + dependency.val(), function (data) { if (counter > curCounter) { return; // Lost race } dependent.find("option").filter(function (t) {return !!$(this).attr("value")}).remove(); if (data.data.length > 0) { $.each(data.data, function (k, s) { dependent.append($("