/*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($("