Issues with multiple filters

Hi… My page has a director and a category tag, and currently when I select director, I get the posts in that category, and when I select category, I only get the posts in that category. But I want to show posts that meet both conditions when selecting multiple tags. How can I do that?

<?php snippet('header');

$directors = page('works')->children()->listed()->pluck('director', ',', true);
$uniqueDirectors = array_unique($directors);

$categories = page('works')->children()->listed()->pluck('category', ',', true);
$uniqueCategories = array_unique($categories);

$works = page('works')->children()->listed()->sortBy('date', 'desc');
?>

<section class="works-list" data-barba="container">
    <div class="works-list-top">
        <div class="list-top-category">
            <div class="top-category-director">
                <div class="category-director-title">director</div>
                <div class="category-director-list">
                    <?php foreach ($uniqueDirectors as $director) : ?>
                        <span class="filter-director" data-director="<?= $director ?>"><?= $director ?></span>
                    <?php endforeach; ?>
                </div>
            </div>
            <div class="top-category-category">
                <div class="category-category-title">category of work</div>
                <div class="category-category-list">
                    <?php foreach ($uniqueCategories as $category) : ?>
                        <span class="filter-category" data-category="<?= $category ?>"><?= $category ?></span>
                    <?php endforeach; ?>
                </div>
            </div>
        </div>
        <div class="list-top-toggle"></div>
    </div>
    <div class="works-list-content">
        <?php foreach ($works as $work) :
            // Additional data attributes for filtering
            $director = $work->director()->html();
            $category = $work->category()->html();
            $coverImage = $work->cover()->toFile();
            $client = $work->client()->html();
            $campaign = $work->campaign()->html();
            $date = $work->date()->toDate('Y'); // 'Y' format will display only the year
            ?>
            <a class="list-thum-link filterable" href="<?= $work->url() ?>" data-director="<?= $director ?>" data-category="<?= $category ?>">
                <div class="list-thum">
                    <?php if ($coverImage) : ?>
                        <?php $resizedImage = $coverImage->resize(800, null); ?>
                        <img src="<?= $resizedImage->url() ?>" class="list-thum-image">
                    <?php endif; ?>
                    <div class="list-thum-content">
                        <div class="list-thum-title">
                            <h3><?= $client ?></h3>
                            <h5><?= $category ?></h5>
                        </div>
                        <h4 class="list-thum-name"><?= $campaign ?></h4>
                        <h4 class="list-thum-year"><?= $date ?></h4>
                    </div>
                </div>
            </a>
        <?php endforeach; ?>

    </div>
</section>

<?php snippet('footer'); ?>

<script>
document.addEventListener('DOMContentLoaded', function () {
    const filterButtons = document.querySelectorAll('.filter-director, .filter-category');

    filterButtons.forEach(button => {
        button.addEventListener('click', function () {
            const filterValue = this.getAttribute('data-director') || this.getAttribute('data-category');

            const itemsToHide = document.querySelectorAll('.filterable');
            itemsToHide.forEach(item => item.style.display = 'none');

            const itemsToShow = document.querySelectorAll(`[data-director="${filterValue}"], [data-category="${filterValue}"]`);
            itemsToShow.forEach(item => item.style.display = 'block');

            filterButtons.forEach(button => {
                button.style.fontWeight = 'normal';
            });

            this.style.fontWeight = 'bold';
        });
    });
});
</script>

Given that you are doing your filtering with javascript, this is not specific to Kirby.

<script>
document.addEventListener('DOMContentLoaded', function () {
    const filterButtons = document.querySelectorAll('.filter-director, .filter-category');

    filterButtons.forEach(button => {
        button.addEventListener('click', function () {
            const filterValue = this.getAttribute('data-director') || this.getAttribute('data-category');

            const itemsToHide = document.querySelectorAll('.filterable');
            itemsToHide.forEach(item => item.style.display = 'none');

            const itemsToShow = document.querySelectorAll(`[data-director="${filterValue}"], [data-category="${filterValue}"]`);
            itemsToShow.forEach(item => item.style.display = 'block');

            filterButtons.forEach(button => {
                button.style.fontWeight = 'normal';
            });

            this.style.fontWeight = 'bold';
        });
    });
});
</script>

To point you in the right direction: when you click on a filter, and then on the second filter, the second filter disregards the first. Your logic isn’t keeping track of what is already filtered.
Instead of hiding everything, and then showing everything that matches what the current button clicked has for attribute, you’d need a different logic.

Alternatively, you could do the filtering with Kirby.
Have a look at Filter collections by tags | Kirby CMS
and Filtering compendium | Kirby CMS

You can also look at how the starterkit implements tag filtering: GitHub - getkirby/starterkit: Kirby's sample site – the easiest way to get started with Kirby