Add filter to tags

This commit is contained in:
2026-01-19 21:27:25 +11:00
parent fb4bb6a16d
commit 736dced60c
+67 -17
View File
@@ -16,26 +16,39 @@
<div id="tag-cloud-container" style="width: 100%; height: 400px;"></div>
</div>
<!-- Sort Controls -->
<div class="flex flex-wrap gap-2 mb-6">
<span class="text-gray-700 font-medium self-center mr-2">{% trans "Sort by:" %}</span>
<a href="?sort=name" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'name' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Name (A-Z)" %}
</a>
<a href="?sort=name_desc" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'name_desc' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Name (Z-A)" %}
</a>
<a href="?sort=count" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'count' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Most Used" %}
</a>
<a href="?sort=count_asc" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'count_asc' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Least Used" %}
</a>
<!-- Sort Controls and Filter -->
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 mb-6">
<div class="flex flex-wrap gap-2">
<span class="text-gray-700 font-medium self-center mr-2">{% trans "Sort by:" %}</span>
<a href="?sort=name" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'name' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Name (A-Z)" %}
</a>
<a href="?sort=name_desc" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'name_desc' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Name (Z-A)" %}
</a>
<a href="?sort=count" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'count' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Most Used" %}
</a>
<a href="?sort=count_asc" class="sort-btn px-3 py-1 rounded text-sm {% if current_sort == 'count_asc' %}bg-blue-500 text-white{% else %}bg-gray-200 text-gray-700 hover:bg-gray-300{% endif %}">
{% trans "Least Used" %}
</a>
</div>
<!-- Quick Filter Input -->
<div class="w-full sm:w-64 relative">
<input type="text" id="filter-tags-input" placeholder="{% trans 'Filter tags...' %}"
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
<svg class="h-4 w-4 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
</svg>
</div>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4" id="tags-grid">
{% for tag in tags %}
<a href="{% url 'tag-detail' tag.slug %}" class="block group">
<a href="{% url 'tag-detail' tag.slug %}" class="block group tag-item" data-tag-name="{{ tag.name|lower }}">
<div
class="tag-card rounded-lg p-2 h-full flex flex-col items-center justify-center text-center shadow-md hover:shadow-lg transition-all duration-200">
<div class="mb-2">
@@ -88,6 +101,11 @@
</div>
{% endfor %}
</div>
<!-- No results message (hidden by default) -->
<div id="no-results-message" class="hidden col-span-full text-center py-8 text-gray-500">
{% trans "No matching tags found." %}
</div>
</div>
<!-- Include ECharts and wordcloud extension -->
@@ -191,5 +209,37 @@
myChart.resize();
});
});
// Quick filter functionality
document.addEventListener('DOMContentLoaded', function() {
const filterInput = document.getElementById('filter-tags-input');
const tagItems = document.querySelectorAll('.tag-item');
const noResultsMessage = document.getElementById('no-results-message');
if (filterInput && tagItems.length > 0) {
filterInput.addEventListener('keyup', function() {
const filterTerm = this.value.toLowerCase().trim();
let visibleCount = 0;
tagItems.forEach(function(item) {
const tagName = item.getAttribute('data-tag-name');
if (tagName && tagName.includes(filterTerm)) {
item.style.display = '';
visibleCount++;
} else {
item.style.display = 'none';
}
});
// Show/hide no results message
if (visibleCount === 0 && filterTerm.length > 0) {
noResultsMessage.classList.remove('hidden');
} else {
noResultsMessage.classList.add('hidden');
}
});
}
});
</script>
{% endblock %}