Skip to content
Advertisement

dynamically display posts of a user-chosen category without reloading page

I have a blog posts page that looks similar to this: https://magnolia.com/blog/

What I want to do is when the user clicks on a category, only posts of that type display below the search. The above page accomplishes that by updating the whole page, but I want the posts to change their display to none so the page doesn’t have to get reloaded every time and so the featured post stays on the page. I have a list of links that display the tags for the posts, with their IDs being the possible post tag IDs.

<div class="page-links" >
        <ul class="link-list">
          <li class="link-list-item"><a href="#0" id="0">All</a></li>
          <li class="link-list-item"><a href="#467" id="467">Joy</a></li>
          <li class="link-list-item"><a href="#888" id="888">Forgiveness</a></li>
          <li class="link-list-item"><a href="#830" id="830">Family</a></li>
          <li class="link-list-item"><a href="#1014" id="1014">Faith</a></li>
          <li class="link-list-item"><a href="#1018" id="1018">Temples</a></li>
          <li class="link-list-item"><a href="#950" id="950">Agency</a></li>
          <li class="link-list-item"><a href="#430" id="430">Grace</a></li>
          <li class="link-list-item"><a href="#1288" id="1288">Revelation</a></li>
         </ul>
        </div>

The posts are displayed using this code ($class_list being a list of all the tag IDs associated with that post)

<div class="post-block <?php echo $class_list; ?>">
    <div class="post-title">
        <h3><a href="<?php echo get_the_permalink($article->ID); ?>"><?php echo get_the_title($article->ID); ?></a></h3>
    </div>
    <div class="post-content article-sub" style="position: relative;">
        <?php echo wp_trim_words(get_the_excerpt(), $num_words, $more_text);?>
    </div>
</div>

So, what I want is when a user clicks on “Joy”, all of the posts with the class “467” are displayed, but all of the posts that do not have that class are hidden with display: none. And if “All” is clicked, all posts are displayed. I know I have to use a hook in my .js file, but I am not very familiar with it and could use any help I can get. Thank you!

Advertisement

Answer

The easy way would be to use a javascript framework and leverage a for-each of some sort. Barring that, here’s a native js way:

First off, you can’t have an html id attribute start with a number. Let’s assume you’ve prefixed all your ids with “tag_”.

Javascript (uses ES6 – make note if you’re supporting old browsers)

<script type="text/javascript">
    var listElement         = document.querySelector(".link-list")
    var postBlockElements   = document.querySelectorAll(".post-block")

    listElement.addEventListener("click", e => {
        if(e.target.tagName !== "A") return;

        let id = e.target.id  

        postBlockElements.forEach(el => {
            el.style.display = el.classList.contains(id) || id === "tag_0"
                ? "block"
                : "none"
        })
    })      
</script>

This is a way, anyway (hopefully). I’m assuming a CMS isn’t always flexible so we’re working with what you’ve provided.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement