mirror of
https://github.com/pretix/pretix.git
synced 2026-05-10 16:04:02 +00:00
Address form: Reduce useless XHR calls
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// Responses are expected to only depend on the GET parameters passed, so we can have a little client-side cache
|
||||||
|
// to prevent fetching the same thing many times.
|
||||||
|
var responseCache = {};
|
||||||
|
|
||||||
$("[data-address-information-url]").each(function () {
|
$("[data-address-information-url]").each(function () {
|
||||||
let xhr;
|
let xhr;
|
||||||
const form = $(this);
|
const form = $(this);
|
||||||
@@ -21,31 +25,12 @@ $(function () {
|
|||||||
dependents[$(this).attr("name").split("-").pop()] = $(this)
|
dependents[$(this).attr("name").split("-").pop()] = $(this)
|
||||||
})
|
})
|
||||||
|
|
||||||
const update = function (ev) {
|
if (!Object.values(dependents).some((el) => el.length)) {
|
||||||
if (xhr) {
|
// No address fields found, do not create request
|
||||||
xhr.abort();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dependents.state.prop("data-selected-value", dependents.state.val());
|
const update_form = function (data) {
|
||||||
if (dependents.transmission_type) {
|
|
||||||
dependents.transmission_type.prop("data-selected-value", dependents.transmission_type.val());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var k in dependents) dependents[k].prop("disabled", true);
|
|
||||||
loader.show();
|
|
||||||
var url = new URL(baseUrl, location.href);
|
|
||||||
// Address depends on all annotated fields
|
|
||||||
form.find("[data-trigger-address-info]").each(function () {
|
|
||||||
// Remove prefix of the form to get actual field name
|
|
||||||
if (($(this).attr("type") === "radio" || $(this).attr("type") === "checkbox") && !$(this).prop("checked")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
url.searchParams.append($(this).attr("name").split("-").pop(), $(this).val());
|
|
||||||
})
|
|
||||||
if (dependents.transmission_type) {
|
|
||||||
url.searchParams.append("transmission_type_required", !dependents.transmission_type.find("option[value='-']").length);
|
|
||||||
}
|
|
||||||
xhr = $.getJSON(url, function (data) {
|
|
||||||
var selected_state = dependents.state.prop("data-selected-value");
|
var selected_state = dependents.state.prop("data-selected-value");
|
||||||
if (selected_state) dependents.state.prop("data-selected-value", "");
|
if (selected_state) dependents.state.prop("data-selected-value", "");
|
||||||
dependents.state.find("option:not([value=''])").remove();
|
dependents.state.find("option:not([value=''])").remove();
|
||||||
@@ -106,18 +91,63 @@ $(function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var k in dependents) dependents[k].prop("disabled", false);
|
for (var k in dependents) dependents[k].prop("disabled", false);
|
||||||
}).always(function() {
|
|
||||||
loader.hide();
|
loader.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = function (ev) {
|
||||||
|
if (xhr) {
|
||||||
|
xhr.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
dependents.state.prop("data-selected-value", dependents.state.val());
|
||||||
|
if (dependents.transmission_type) {
|
||||||
|
dependents.transmission_type.prop("data-selected-value", dependents.transmission_type.val());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var k in dependents) dependents[k].prop("disabled", true);
|
||||||
|
loader.show();
|
||||||
|
var url = new URL(baseUrl, location.href);
|
||||||
|
// Address depends on all annotated fields
|
||||||
|
form.find("[data-trigger-address-info]").each(function () {
|
||||||
|
// Remove prefix of the form to get actual field name
|
||||||
|
if (($(this).attr("type") === "radio" || $(this).attr("type") === "checkbox") && !$(this).prop("checked")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
url.searchParams.append($(this).attr("name").split("-").pop(), $(this).val());
|
||||||
|
})
|
||||||
|
if (dependents.transmission_type) {
|
||||||
|
url.searchParams.append("transmission_type_required", !dependents.transmission_type.find("option[value='-']").length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(url in responseCache)) {
|
||||||
|
responseCache[url] = new Promise((resolve, reject) => {
|
||||||
|
xhr = $.ajax({
|
||||||
|
dataType: "json",
|
||||||
|
url: url,
|
||||||
|
timeout: 3000,
|
||||||
|
success: resolve,
|
||||||
}).fail(function(){
|
}).fail(function(){
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.resolve(responseCache[url]).then(function (data) {
|
||||||
|
responseCache[url] = data;
|
||||||
|
update_form(data);
|
||||||
|
}).catch(function () {
|
||||||
|
delete responseCache[url];
|
||||||
// In case of errors, show everything and require nothing, we can still handle errors in backend
|
// In case of errors, show everything and require nothing, we can still handle errors in backend
|
||||||
for(var k in dependents) {
|
for (var k in dependents) {
|
||||||
const dependent = dependents[k],
|
const dependent = dependents[k],
|
||||||
visible = true,
|
visible = true,
|
||||||
required = false;
|
required = false;
|
||||||
|
|
||||||
dependent.closest(".form-group").toggle(visible).toggleClass('required', required);
|
dependent.closest(".form-group").toggle(visible).toggleClass('required', required);
|
||||||
dependent.prop("required", required);
|
dependent.prop("required", required).prop("disabled", false);
|
||||||
}
|
}
|
||||||
|
}).finally(function () {
|
||||||
|
loader.hide();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
update();
|
update();
|
||||||
|
|||||||
Reference in New Issue
Block a user