Available features for the current selection are:
`;
// Group features by category
let categories_map = {};
features.forEach(feature => {
const cat_name = feature.category.name;
if (!categories_map[cat_name]) {
categories_map[cat_name] = [];
}
categories_map[cat_name].push(feature);
});
// Convert to array and display
let categories = Object.entries(categories_map).map(([name, feats]) => ({name, features: feats}));
categories.forEach((category, cat_idx) => {
if (cat_idx % 4 == 0) {
let new_row = document.createElement('div');
new_row.setAttribute('class', 'row');
new_row.id = 'category_'+parseInt(cat_idx/4)+'_row';
output.appendChild(new_row);
}
let col_element = document.createElement('div');
col_element.setAttribute('class', 'col-md-3 col-sm-6 mb-2');
col_element.appendChild(createCategoryCard(category.name, category.features, init_categories_expanded));
document.getElementById('category_'+parseInt(cat_idx/4)+'_row').appendChild(col_element);
});
}
// returns a Promise
// the promise is resolved when we recieve status code 200 from the AJAX request
// the JSON response for the request is returned in such case
// the promise is rejected when the status code is not 200
// the status code is returned in such case
function sendAjaxRequestForJsonResponse(url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
// disable cache, thanks to: https://stackoverflow.com/questions/22356025/force-cache-control-no-cache-in-chrome-via-xmlhttprequest-on-f5-reload
xhr.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0");
xhr.setRequestHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT");
xhr.setRequestHeader("Pragma", "no-cache");
xhr.onload = function () {
if (xhr.status == 200) {
resolve(JSON.parse(xhr.response));
} else {
reject("Got response:"+xhr.response+" (Status Code: "+xhr.status+")");
}
}
xhr.send();
});
}
function fillVehicles(vehicles, vehicle_id_to_select) {
var output = document.getElementById('vehicle_list');
output.innerHTML = '