ENHANCEMENT Improve article filtering UI and functionality with new button filters and updated CSS styles
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Nonimart 2025-10-22 14:56:54 +02:00
parent b3c21f4648
commit 9b460a9639
3 changed files with 198 additions and 95 deletions

View File

@ -1,6 +1,7 @@
.post-grid {
&__toolbar {
@apply flex flex-col md:grid md:grid-cols-2 gap-4 md:items-center justify-between pb-12;
/* @apply flex flex-col md:grid md:grid-cols-2 gap-4 md:items-center justify-between pb-12; */
@apply pb-12 grid grid-cols-2 gap-4 gap-y-8 items-end;
.post-count {
@apply flex items-end gap-2;
@ -16,6 +17,7 @@
.search-bar {
@apply md:justify-self-end text-primary relative;
&:after {
@apply absolute top-1/2 -translate-y-1/2;
content: '';
@ -29,28 +31,27 @@
background-size: contain;
}
input {
@apply w-full md:w-auto py-2 px-4 border border-primary rounded-full;
@apply w-full md:w-auto !py-4 px-4 border border-primary rounded-full text-base;
padding-right: 33px;
line-height: 1.5;
height: auto;
width: 500px;
max-width: 100%;
&::placeholder {
@apply text-base font-normal text-carhop-green-700;
@apply !text-base font-normal text-carhop-green-700;
}
}
}
}
&__toolbar-actions {
@apply col-span-2 flex flex-wrap items-center gap-4;
select {
@apply w-full md:w-auto border border-carhop-green-700 text-carhop-green-700 rounded-full py-2 px-4 max-w-full text-base;
@apply w-full md:w-auto border border-carhop-green-700 text-carhop-green-700 rounded-full !py-4 px-4 max-w-full text-base;
line-height: 1.5;
height: auto;
appearance: none; /* Disable the default arrow */
-webkit-appearance: none; /* For WebKit-based browsers */
-moz-appearance: none; /* For Firefox */
/* width: 100%;
padding: 10px 35px 10px 10px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px; */
background-color: #fff;
background-image: url('../resources/img/elements/select-drop-button.svg');
@ -60,6 +61,36 @@
cursor: pointer;
}
select[name='sort_by'] {
@apply pr-12 w-fit justify-self-end;
}
}
.search-by {
&__label {
@apply text-primary font-semibold nunito;
}
.search-by__buttons {
@apply flex items-center border border-primary border-solid w-fit;
button {
@apply block font-normal nunito text-primary py-2 px-4;
&[aria-selected='true'] {
@apply bg-primary text-white;
&:hover {
@apply bg-primary text-white;
}
}
&:hover {
@apply bg-carhop-green-50;
}
}
&[data-filter='thematique'] {
}
}
}
&__toolbar-actions {
@apply flex flex-wrap items-center gap-4 justify-self-end;
select[name='etiquettes'] {
/* @apply bg-blue-300; */
}
@ -67,13 +98,36 @@
select[name='auteurs'] {
/* @apply bg-red-300; */
}
select[name='sort_by'] {
@apply md:ml-auto pr-12;
}
}
&__list {
@apply grid grid-cols-1 lg:grid-cols-2 gap-8;
}
}
body:has(.search-by button[data-filter='thematique'][aria-selected='true']) {
.post-grid__toolbar-actions {
select[name='auteurs'],
.search-bar {
@apply hidden;
}
}
}
body:has(.search-by button[data-filter='auteur'][aria-selected='true']) {
.post-grid__toolbar-actions {
select[name='etiquettes'],
.search-bar {
@apply hidden;
}
}
}
body:has(.search-by button[data-filter='occurence'][aria-selected='true']) {
.post-grid__toolbar-actions {
select[name='etiquettes'],
select[name='auteurs'] {
@apply hidden;
}
}
}

View File

@ -1,68 +1,105 @@
export default function filterArticlesInit() {
const toolbar = document.querySelector('.post-grid__toolbar');
if (!toolbar) return;
const postGridToolbarActions = toolbar.querySelector('.post-grid__toolbar-actions');
const etiquettesSelect = toolbar.querySelector('select[name="etiquettes"]') as HTMLSelectElement;
const auteursSelect = toolbar.querySelector('select[name="auteurs"]') as HTMLSelectElement;
const sortBySelect = toolbar.querySelector('select[name="sort_by"]') as HTMLSelectElement;
const rechercheInput = toolbar.querySelector('.search-bar input') as HTMLInputElement;
async function hydrateArticles() {
const etiquetteValue = etiquettesSelect.value;
const auteurValue = auteursSelect.value;
const sortByValue = sortBySelect.value;
const rechercheValue = rechercheInput.value;
try {
const response = await fetch(
`/wp-json/dynamiques-datas/v1/build/articles?etiquette=${etiquetteValue}&auteur=${auteurValue}&sort_by=${sortByValue}&recherche=${rechercheValue}`
// `/wp-json/dynamiques-datas/v1/build/articles?etiquettes=${etiquettesSelect.value}&auteurs=${auteursSelect.value}&sort_by=${sortBySelect.value}&recherche=${rechercheInput.value}`
);
const data = await response.json();
console.log(data);
const articlesContainer = document.querySelector('.post-grid__list');
if (!articlesContainer) return;
articlesContainer.innerHTML = data.html_template;
updatePostCount(data.post_count);
} catch (error) {
console.error('Erreur lors de la récupération des articles:', error);
}
}
// Écouter les changements sur les selects
postGridToolbarActions.addEventListener('change', (e) => {
hydrateArticles();
});
rechercheInput.addEventListener('input', (e) => {
hydrateArticles();
});
}
function updatePostCount(count: number) {
const postCount = document.querySelector('.post-count__count');
if (!postCount) return;
postCount.innerHTML = count.toString();
}
function scrollToArticlesGridIfHasInitialFilter() {
const articlesGrid = document.querySelector('.articles-grid');
const hasInitialFilter = articlesGrid?.classList.contains('has-initial-filter');
if (!hasInitialFilter || !articlesGrid) return;
setTimeout(() => {
articlesGrid.scrollIntoView({ behavior: 'smooth' });
const etiquettesSelect = document.querySelector(
'.post-grid__toolbar-actions select[name="etiquettes"]'
);
if (!etiquettesSelect) return;
etiquettesSelect.focus();
}, 200);
}
window.addEventListener('load', () => {
scrollToArticlesGridIfHasInitialFilter();
});
export default function filterArticlesInit() {
const toolbar = document.querySelector('.post-grid__toolbar');
if (!toolbar) return;
const postGridToolbarActions = toolbar.querySelector('.post-grid__toolbar-actions');
const etiquettesSelect = toolbar.querySelector('select[name="etiquettes"]') as HTMLSelectElement;
const auteursSelect = toolbar.querySelector('select[name="auteurs"]') as HTMLSelectElement;
const sortBySelect = toolbar.querySelector('select[name="sort_by"]') as HTMLSelectElement;
const rechercheInput = toolbar.querySelector('.search-bar input') as HTMLInputElement;
async function hydrateArticles() {
const etiquetteValue = etiquettesSelect.value;
const auteurValue = auteursSelect.value;
const sortByValue = sortBySelect.value;
const rechercheValue = rechercheInput.value;
try {
const response = await fetch(
`/wp-json/dynamiques-datas/v1/build/articles?etiquette=${etiquetteValue}&auteur=${auteurValue}&sort_by=${sortByValue}&recherche=${rechercheValue}`
);
const data = await response.json();
console.log(data);
const articlesContainer = document.querySelector('.post-grid__list');
if (!articlesContainer) return;
articlesContainer.innerHTML = data.html_template;
updatePostCount(data.post_count);
} catch (error) {
console.error('Erreur lors de la récupération des articles:', error);
}
}
function resetCurrentFilters() {
if (!etiquettesSelect || !auteursSelect || !rechercheInput) return;
etiquettesSelect.value = '';
auteursSelect.value = '';
rechercheInput.value = '';
}
function setFilterByActivebutton(button: HTMLButtonElement) {
const filterByButtons = document.querySelectorAll('.search-by button');
if (!filterByButtons) return;
filterByButtons.forEach((button) => {
button.setAttribute('aria-selected', 'false');
});
button.setAttribute('aria-selected', 'true');
}
function handleFilterArticlesBy() {
const filterByButtons = document.querySelectorAll('.search-by button');
if (!filterByButtons) return;
filterByButtons.forEach((button) => {
button.addEventListener('click', (e) => {
e.preventDefault();
setFilterByActivebutton(button as HTMLButtonElement);
resetCurrentFilters();
hydrateArticles();
});
});
}
// Écouter les changements sur les selects
if (postGridToolbarActions) {
postGridToolbarActions.addEventListener('change', (e) => {
hydrateArticles();
});
}
sortBySelect.addEventListener('change', (e) => {
hydrateArticles();
});
rechercheInput.addEventListener('input', (e) => {
hydrateArticles();
});
// Initialiser le filtrage par boutons
handleFilterArticlesBy();
}
function updatePostCount(count: number) {
const postCount = document.querySelector('.post-count__count');
if (!postCount) return;
postCount.innerHTML = count.toString();
}
function scrollToArticlesGridIfHasInitialFilter() {
const articlesGrid = document.querySelector('.articles-grid');
const hasInitialFilter = articlesGrid?.classList.contains('has-initial-filter');
if (!hasInitialFilter || !articlesGrid) return;
setTimeout(() => {
articlesGrid.scrollIntoView({ behavior: 'smooth' });
const etiquettesSelect = document.querySelector(
'.post-grid__toolbar-actions select[name="etiquettes"]'
) as HTMLSelectElement;
if (!etiquettesSelect) return;
etiquettesSelect.focus();
}, 200);
}
window.addEventListener('load', () => {
scrollToArticlesGridIfHasInitialFilter();
});

View File

@ -38,6 +38,21 @@ $thematiques = get_terms(array(
<div class="content-section__inner">
<div class="post-grid__toolbar">
<div class="search-by">
<p class="search-by__label">Filtrer par</p>
<div class="search-by__buttons" data-filter="thematique">
<button data-filter="thematique" aria-selected="true">Thématique</button>
<button data-filter="auteur" aria-selected="false">Auteur·e</button>
<button data-filter="occurence" aria-selected="false">Occurence Textuelle</button>
</div>
</div>
<select name="sort_by">
<option value="date_desc" selected><?php _e('Numéros récents en premier', 'dynamiques'); ?></option>
<option value="date_asc"><?php _e('Numéros anciens en premier', 'dynamiques'); ?></option>
<option value="title_asc"><?php _e('Par ordre alphabétique', 'dynamiques'); ?></option>
</select>
<h2 class="post-count">
<span class="post-count__count">
<?php echo $post_count; ?>
@ -46,12 +61,11 @@ $thematiques = get_terms(array(
<?php _e('articles', 'dynamiques'); ?>
</span>
</h2>
<div class="search-bar">
<input type="text" placeholder="<?php _e('Rechercher par mot-clé', 'dynamiques'); ?>">
</div>
<div class="post-grid__toolbar-actions">
<div class="search-bar">
<input type="text" placeholder="<?php _e('Rechercher par mot-clé', 'dynamiques'); ?>">
</div>
<select name="etiquettes">
<option value=""><?php _e('Tous les tags', 'dynamiques'); ?></option>
@ -62,19 +76,17 @@ $thematiques = get_terms(array(
<?php endforeach; ?>
</select>
<select name="auteurs">
<option value="1"><?php _e('Tous·tes les auteur·e·s', 'dynamiques'); ?></option>
<option value=""><?php _e('Tous·tes les auteur·e·s', 'dynamiques'); ?></option>
<?php foreach ($authors as $author) : ?>
<option value="<?php echo $author->ID; ?>"><?php echo $author->post_title; ?></option>
<?php endforeach; ?>
</select>
<select name="sort_by">
<option value="date_desc" selected><?php _e('Numéros récents en premier', 'dynamiques'); ?></option>
<option value="date_asc"><?php _e('Numéros anciens en premier', 'dynamiques'); ?></option>
<option value="title_asc"><?php _e('Par ordre alphabétique', 'dynamiques'); ?></option>
</select>
</div>
</div>
<ul class="post-grid__list">