feat: Add adaptive multi-column layout for categories and tags checkboxes
Implemented responsive grid system for product form checkboxes to improve UX when dealing with multiple categories and tags. Changes: - Added CSS Grid layout with adaptive columns (1-4 based on screen width) - Mobile (< 768px): 1 column - Tablet (≥ 768px): 2 columns - Desktop (≥ 1200px): 3 columns - Wide screens (≥ 1600px): 4 columns - Compact spacing (0.35rem gap) for better density - Enhanced checkbox styling with hover effects and selected state - JavaScript fallback for forced grid application and responsive resizing - Improved form container width (col-12 col-xl-10) for better space usage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,10 +2,116 @@
|
||||
|
||||
{% block title %}{% if object %}Редактировать товар{% else %}Создать товар{% endif %}{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
/* Адаптивная grid-система для чекбоксов категорий и тегов */
|
||||
/* Нацеливаемся на любой UL внутри .checkbox-grid */
|
||||
#id_categories,
|
||||
#id_tags,
|
||||
.checkbox-grid ul,
|
||||
.checkbox-grid > ul,
|
||||
.checkbox-grid div > ul,
|
||||
.checkbox-grid * ul {
|
||||
display: grid !important;
|
||||
gap: 0.35rem !important;
|
||||
list-style: none !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
/* 1 столбец на маленьких экранах */
|
||||
grid-template-columns: 1fr !important;
|
||||
}
|
||||
|
||||
/* 2 столбца на средних экранах (≥768px) */
|
||||
@media (min-width: 768px) {
|
||||
#id_categories,
|
||||
#id_tags,
|
||||
.checkbox-grid ul,
|
||||
.checkbox-grid > ul,
|
||||
.checkbox-grid div > ul,
|
||||
.checkbox-grid * ul {
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3 столбца на больших экранах (≥1200px) */
|
||||
@media (min-width: 1200px) {
|
||||
#id_categories,
|
||||
#id_tags,
|
||||
.checkbox-grid ul,
|
||||
.checkbox-grid > ul,
|
||||
.checkbox-grid div > ul,
|
||||
.checkbox-grid * ul {
|
||||
grid-template-columns: repeat(3, 1fr) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 4 столбца на очень больших экранах (≥1600px) */
|
||||
@media (min-width: 1600px) {
|
||||
#id_categories,
|
||||
#id_tags,
|
||||
.checkbox-grid ul,
|
||||
.checkbox-grid > ul,
|
||||
.checkbox-grid div > ul,
|
||||
.checkbox-grid * ul {
|
||||
grid-template-columns: repeat(4, 1fr) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Стилизация элементов списка */
|
||||
#id_categories li,
|
||||
#id_tags li,
|
||||
.checkbox-grid li {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Стилизация чекбоксов */
|
||||
#id_categories label,
|
||||
#id_tags label,
|
||||
.checkbox-grid label {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
margin-bottom: 0 !important;
|
||||
padding: 0.4rem 0.6rem !important;
|
||||
background: white !important;
|
||||
border-radius: 0.375rem !important;
|
||||
transition: all 0.2s ease !important;
|
||||
cursor: pointer !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
#id_categories label:hover,
|
||||
#id_tags label:hover,
|
||||
.checkbox-grid label:hover {
|
||||
background: #e9ecef !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05) !important;
|
||||
}
|
||||
|
||||
#id_categories input[type="checkbox"],
|
||||
#id_tags input[type="checkbox"],
|
||||
.checkbox-grid input[type="checkbox"] {
|
||||
margin-right: 0.5rem !important;
|
||||
cursor: pointer !important;
|
||||
width: 18px !important;
|
||||
height: 18px !important;
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
/* Стиль для выбранных чекбоксов */
|
||||
#id_categories li:has(input[type="checkbox"]:checked) label,
|
||||
#id_tags li:has(input[type="checkbox"]:checked) label,
|
||||
.checkbox-grid li:has(input[type="checkbox"]:checked) label {
|
||||
background: #e7f3ff !important;
|
||||
border-left: 3px solid #0d6efd !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="col-12 col-xl-10">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
@@ -76,7 +182,7 @@
|
||||
<i class="bi bi-plus-circle"></i> Новая
|
||||
</a>
|
||||
</div>
|
||||
<div class="p-3 bg-light rounded">
|
||||
<div class="p-3 bg-light rounded checkbox-grid">
|
||||
{{ form.categories }}
|
||||
</div>
|
||||
{% if form.categories.help_text %}
|
||||
@@ -90,7 +196,7 @@
|
||||
<!-- Теги -->
|
||||
<div class="mb-3">
|
||||
{{ form.tags.label_tag }}
|
||||
<div class="p-3 bg-light rounded">
|
||||
<div class="p-3 bg-light rounded checkbox-grid">
|
||||
{{ form.tags }}
|
||||
</div>
|
||||
{% if form.tags.help_text %}
|
||||
@@ -400,3 +506,78 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
// Диагностика и принудительное применение grid для чекбоксов
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('=== Checkbox Grid Diagnostic ===');
|
||||
|
||||
// Ищем все UL элементы внутри .checkbox-grid
|
||||
const checkboxGrids = document.querySelectorAll('.checkbox-grid');
|
||||
|
||||
checkboxGrids.forEach((grid, index) => {
|
||||
console.log(`Grid ${index}:`, grid);
|
||||
|
||||
// Ищем все UL внутри этого grid
|
||||
const lists = grid.querySelectorAll('ul');
|
||||
console.log(` Found ${lists.length} UL elements`);
|
||||
|
||||
lists.forEach((ul, ulIndex) => {
|
||||
console.log(` UL ${ulIndex}:`, ul);
|
||||
console.log(` ID: ${ul.id}`);
|
||||
console.log(` Current display: ${window.getComputedStyle(ul).display}`);
|
||||
console.log(` Current grid-template-columns: ${window.getComputedStyle(ul).gridTemplateColumns}`);
|
||||
|
||||
// Принудительно применяем grid стили
|
||||
ul.style.setProperty('display', 'grid', 'important');
|
||||
ul.style.setProperty('list-style', 'none', 'important');
|
||||
ul.style.setProperty('padding', '0', 'important');
|
||||
ul.style.setProperty('margin', '0', 'important');
|
||||
ul.style.setProperty('gap', '0.35rem', 'important');
|
||||
|
||||
// Определяем количество колонок на основе ширины экрана
|
||||
const width = window.innerWidth;
|
||||
let columns = 1;
|
||||
if (width >= 1600) columns = 4;
|
||||
else if (width >= 1200) columns = 3;
|
||||
else if (width >= 768) columns = 2;
|
||||
|
||||
ul.style.setProperty('grid-template-columns', `repeat(${columns}, 1fr)`, 'important');
|
||||
|
||||
console.log(` Applied ${columns} columns`);
|
||||
console.log(` New display: ${window.getComputedStyle(ul).display}`);
|
||||
});
|
||||
});
|
||||
|
||||
// Также проверяем прямые ID
|
||||
['id_categories', 'id_tags'].forEach(id => {
|
||||
const element = document.getElementById(id);
|
||||
if (element) {
|
||||
console.log(`Found element with ID: ${id}`, element);
|
||||
console.log(` Tag name: ${element.tagName}`);
|
||||
console.log(` Parent: ${element.parentElement.className}`);
|
||||
} else {
|
||||
console.log(`Element with ID ${id} NOT found`);
|
||||
}
|
||||
});
|
||||
|
||||
// Пересчитываем при изменении размера окна
|
||||
let resizeTimeout;
|
||||
window.addEventListener('resize', function() {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(function() {
|
||||
const width = window.innerWidth;
|
||||
let columns = 1;
|
||||
if (width >= 1600) columns = 4;
|
||||
else if (width >= 1200) columns = 3;
|
||||
else if (width >= 768) columns = 2;
|
||||
|
||||
document.querySelectorAll('.checkbox-grid ul, #id_categories, #id_tags').forEach(ul => {
|
||||
ul.style.setProperty('grid-template-columns', `repeat(${columns}, 1fr)`, 'important');
|
||||
});
|
||||
}, 250);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user