feat: add subcategory support for catalog and admin
All checks were successful
Build and Push Docker Image / build (push) Successful in 30s
All checks were successful
Build and Push Docker Image / build (push) Successful in 30s
- Introduced `Subcategory` model with migration and unique slug constraint per category - Enabled subcategory assignment for items with validation to ensure category matching - Updated catalog views to handle subcategories, filtering items accordingly - Enhanced templates (`index.html`, `side-bar.html`, `item-list.html`, `detail.html`) to display subcategories - Added dynamic subcategory dropdown in Django admin with category filtering - Created JavaScript for admin subcategory handling and AJAX population - Wrote comprehensive tests for subcategory functionality in views and admin
This commit is contained in:
67
static/items/admin/item-subcategory.js
Normal file
67
static/items/admin/item-subcategory.js
Normal file
@@ -0,0 +1,67 @@
|
||||
(function () {
|
||||
function getSubcategoriesUrl() {
|
||||
return window.location.pathname.replace(/\/(?:add|\d+\/change)\/?$/, '/subcategories/');
|
||||
}
|
||||
|
||||
function setOptions(select, subcategories, selectedId) {
|
||||
var emptyOption = Array.prototype.find.call(select.options, function (option) {
|
||||
return option.value === '';
|
||||
});
|
||||
var emptyLabel = emptyOption ? emptyOption.textContent : '---------';
|
||||
|
||||
select.innerHTML = '';
|
||||
select.appendChild(new Option(emptyLabel, ''));
|
||||
|
||||
subcategories.forEach(function (subcategory) {
|
||||
var option = new Option(subcategory.name, subcategory.id);
|
||||
|
||||
if (String(subcategory.id) === String(selectedId)) {
|
||||
option.selected = true;
|
||||
}
|
||||
|
||||
select.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
function loadSubcategories(categorySelect, subcategorySelect, selectedId) {
|
||||
if (!categorySelect.value) {
|
||||
setOptions(subcategorySelect, [], '');
|
||||
return;
|
||||
}
|
||||
|
||||
var url = getSubcategoriesUrl() + '?category_id=' + encodeURIComponent(categorySelect.value);
|
||||
|
||||
fetch(url, {
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load subcategories.');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
setOptions(subcategorySelect, data.subcategories || [], selectedId);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var categorySelect = document.getElementById('id_category');
|
||||
var subcategorySelect = document.getElementById('id_subcategory');
|
||||
|
||||
if (!categorySelect || !subcategorySelect) {
|
||||
return;
|
||||
}
|
||||
|
||||
categorySelect.addEventListener('change', function () {
|
||||
loadSubcategories(categorySelect, subcategorySelect, '');
|
||||
});
|
||||
|
||||
if (!categorySelect.value) {
|
||||
setOptions(subcategorySelect, [], '');
|
||||
}
|
||||
});
|
||||
}());
|
||||
Reference in New Issue
Block a user