loko/streetup/interventions/static/interventions/admin_operation_template_dynamic.js
2026-07-22 14:48:40 +02:00

157 lines
5.5 KiB
JavaScript

/**
* Dynamic filtering for OperationTemplate admin form
* Updates categories based on thematic selection
* Updates asset models based on categories selection
*/
(function() {
'use strict';
function initDynamicFiltering() {
if (typeof django === 'undefined' || typeof django.jQuery === 'undefined') {
// Retry shortly if Django's bundled jQuery is not yet present
setTimeout(initDynamicFiltering, 100);
return;
}
var $ = django.jQuery;
$(document).ready(function() {
var $thematic = $('#id_thematic');
var $categoriesFrom = $('#id_categories_from');
var $categoriesTo = $('#id_categories_to');
var $assetModelsFrom = $('#id_asset_models_from');
var $assetModelsTo = $('#id_asset_models_to');
if (!$thematic.length) return;
/**
* Update categories based on selected thematic
*/
function updateCategories() {
var thematicId = $thematic.val();
if (!thematicId) {
// Clear categories if no thematic selected
$categoriesFrom.empty();
$categoriesTo.empty();
updateAssetModels();
return;
}
// Get current selections
var selectedCategories = $categoriesTo.find('option').map(function() {
return $(this).val();
}).get();
// Fetch filtered categories
$.ajax({
url: '/interventions/ajax/get-categories-by-thematic/',
data: { thematic_id: thematicId },
success: function(data) {
// Clear both lists
$categoriesFrom.empty();
$categoriesTo.empty();
// Populate categories
data.categories.forEach(function(cat) {
var option = $('<option></option>')
.val(cat.id)
.text(cat.name);
// If previously selected, add to "chosen" list
if (selectedCategories.indexOf(String(cat.id)) !== -1) {
$categoriesTo.append(option);
} else {
$categoriesFrom.append(option);
}
});
// Update asset models after categories change
updateAssetModels();
},
error: function() {
console.error('Error fetching categories');
}
});
}
/**
* Update asset models based on selected categories (or thematic if no categories)
*/
function updateAssetModels() {
var thematicId = $thematic.val();
var categoryIds = $categoriesTo.find('option').map(function() {
return $(this).val();
}).get();
if (!thematicId) {
// Clear asset models if no thematic selected
$assetModelsFrom.empty();
$assetModelsTo.empty();
return;
}
// Get current selections
var selectedModels = $assetModelsTo.find('option').map(function() {
return $(this).val();
}).get();
// Fetch filtered asset models
$.ajax({
url: '/interventions/ajax/get-asset-models/',
data: {
thematic_id: thematicId,
category_ids: categoryIds.join(',')
},
success: function(data) {
// Clear both lists
$assetModelsFrom.empty();
$assetModelsTo.empty();
// Populate asset models
data.models.forEach(function(model) {
var option = $('<option></option>')
.val(model.value)
.text(model.display);
// If previously selected, add to "chosen" list
if (selectedModels.indexOf(model.value) !== -1) {
$assetModelsTo.append(option);
} else {
$assetModelsFrom.append(option);
}
});
},
error: function() {
console.error('Error fetching asset models');
}
});
}
// Listen to thematic changes
$thematic.on('change', function() {
updateCategories();
});
// Listen to categories changes using MutationObserver
// (filter_horizontal uses JavaScript to move options, not change events)
if ($categoriesTo.length) {
var observer = new MutationObserver(function(mutations) {
updateAssetModels();
});
observer.observe($categoriesTo[0], {
childList: true,
subtree: true
});
}
});
}
// Start initialization
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initDynamicFiltering);
} else {
initDynamicFiltering();
}
})();