skip to Main Content

I’m trying to hide elements based on class names in a second list by clicking on links from the first list. Items in both lists have corresponding classes. If an item from the second list doesn’t contain at least one class from the clicked "active" item in the first list, it should get the "off" class.

For some reason, I’m not getting the correct results. The items are getting the "off" class, even if they shouldn’t.

Can someone please tell me what I’m doing wrong?

Thanks in advance.

fiddle

Here’s the code snippet:

const show_all = document.querySelector('.all-topics');
const links = document.querySelectorAll('.filter-resources a');
const topics_items = document.querySelectorAll('.filter-topics li');

show_all.addEventListener('click', function(event) {
  topics_items.forEach(topics_item => topics_item.classList.remove('off'));
  event.preventDefault();
});


links.forEach(link => {

  link.addEventListener('click', function(event) {

    links.forEach(link => link.classList.remove('active'));
    this.classList.add('active');
    event.preventDefault();

    const active_resource = document.querySelector('.filter-resources a.active');

    if (active_resource !== undefined && active_resource !== null) {

      let active_resource_filter = active_resource.parentElement;

      let classes = Array.from(active_resource_filter.classList);

      for (let topics_item of topics_items) {

        topics_item.classList.remove('off');

        for (let i = 0, j = classes.length; i < j; i++) {

          if (topics_item.classList.contains(classes[i])) {
            topics_item.classList.remove('off');
          } else {
            topics_item.classList.add('off');
          }
        }

      }

    } else {

      topics_item.classList.remove('off');

    }

  });

});
.off {
  display: none;
}
<ul>
  <li>
    <a href="#" class="all-topics" reset href="#">Show All</a>
  </li>
  <li>
    <header>Resources</header>
    <ul class="filter-resources">
      <li class="branding case-studies content-marketing-storytelling marketing-analytics marketing-services outsourced-marketing sem-paid-advertising seo-organic-search">
        <a class="" href="#">Case Studies</a></li>
      <li class="downloads fractional-cmo marketing-strategy outsourced-marketing">
        <a class="" href="#">Downloads</a></li>
      <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
        <a class="" href="#">Marketing Insights</a></li>
      <li class="marketing-analytics marketing-strategy tools">
        <a class="" href="#">Tools</a>
      </li>
      <li class="company-culture marketing-strategy videos-podcasts">
        <a class="" href="#">Videos &amp;odcasts</a>
      </li>
    </ul>
  </li>
  <li>
    <header>topics</header>
    <ul class="filter-topics">
      <li class="ai digital-marketing marketing-insights social-media">
        <a class="" href="#">AI</a>
      </li>
      <li class="branding marketing-insights marketing-strategy">
        <a class="" href="#">Branding</a>
      </li>
      <li class="business-strategy marketing-insights marketing-planning">
        <a class="" href="#">Business Strategy</a>
      </li>
      <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
        <a class="" href="#">Company Culture</a>
      </li>
      <li class="branding content-marketing-storytelling digital-marketing marketing-insights seo-organic-search">
        <a class="" href="#">Content Marketing &amp; Storytelling</a>
      </li>
      <li class="digital-marketing marketing-insights outsourced-marketing">
        <a class="" href="#">Digital Marketing</a>
      </li>
      <li class="company-culture content-marketing-storytelling eos marketing-insights">
        <a class="" href="#">EOS</a>
      </li>
      <li class="branding case-studies digital-marketing fractional-cmo fractional-cmo-case-studies marketing-strategy social-media">
        <a class="" href="#">Fractional CMO</a>
      </li>
      <li class="fractional-cmo marketing-insights marketing-strategy outsourced-marketing">
        <a class="" href="#">Fractional CMO</a>
      </li>
      <li class="insights">
        <a class="" href="#">Insights</a>
      </li>
      <li class="marketing-analytics marketing-insights outsourced-marketing">
        <a class="" href="#">Marketing Analytics</a>
      </li>
      <li class="digital-marketing marketing-analytics marketing-automation marketing-insights marketing-strategy">
        <a class="" href="#">Marketing Automation</a>
      </li>
      <li class="business-strategy marketing-insights marketing-planning">
        <a class="" href="#">Marketing Planning</a>
      </li>
      <li class="branding case-studies content-marketing-storytelling marketing-analytics marketing-services outsourced-marketing sem-paid-advertising seo-organic-search">
        <a class="" href="#">Marketing Services</a>
      </li>
      <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
        <a class="" href="#">Marketing Strategy</a>
      </li>
      <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
        <a class="" href="#">Outsourced Marketing</a>
      </li>
      <li class="digital-marketing marketing-insights outsourced-marketing sem-paid-advertising seo-organic-search">
        <a class="" href="#">SEM &amp; Paid Advertising</a>
      </li>
      <li class="branding content-marketing-storytelling digital-marketing marketing-insights seo-organic-search">
        <a class="" href="#">SEO &amp; Organic Search</a>
      </li>
      <li class="content-marketing-storytelling digital-marketing marketing-insights social-media">
        <a class="" href="#">Social Media</a>
      </li>
    </ul>
  </li>
</ul>

2

Answers


  1. you can simply use .classList.toggle( className, forcing) method, where forcing argument is a boolean

    const
      show_all     = document.querySelector('.all-topics') 
    , links        = document.querySelector('.filter-resources') 
    , topics_items = document.querySelectorAll('.filter-topics li')
      ;
    show_all.addEventListener('click', ({target:link})=>
      {
      topics_items.forEach(topicItem => topicItem.classList.remove('off'));
      })
    links.addEventListener('click', ({target:link})=>
      {
      if (!link.matches('.filter-resources a')) return;
      let topicsList =  [...link.closest('li').classList];
    
      topics_items.forEach( topicItem => topicItem.classList.toggle('off', !topicsList.some( topic => topicItem.classList.contains(topic) )));
      })
    .off { 
      display: none;
      }
    <ul>
      <li>
        <a href="#" class="all-topics" reset href="#">Show All</a>
      </li>
      <li>
        <header>Resources</header>
        <ul class="filter-resources">
          <li class="branding case-studies content-marketing-storytelling marketing-analytics marketing-services outsourced-marketing sem-paid-advertising seo-organic-search">
            <a class="" href="#">Case Studies</a></li>
          <li class="downloads fractional-cmo marketing-strategy outsourced-marketing">
            <a class="" href="#">Downloads</a></li>
          <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
            <a class="" href="#">Marketing Insights</a></li>
          <li class="marketing-analytics marketing-strategy tools">
            <a class="" href="#">Tools</a>
          </li>
          <li class="company-culture marketing-strategy videos-podcasts">
            <a class="" href="#">Videos &amp;odcasts</a>
          </li>
        </ul>
      </li>
      <li>
        <header>topics</header>
        <ul class="filter-topics">
          <li class="ai digital-marketing marketing-insights social-media">
            <a class="" href="#">AI</a>
          </li>
          <li class="branding marketing-insights marketing-strategy">
            <a class="" href="#">Branding</a>
          </li>
          <li class="business-strategy marketing-insights marketing-planning">
            <a class="" href="#">Business Strategy</a>
          </li>
          <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
            <a class="" href="#">Company Culture</a>
          </li>
          <li class="branding content-marketing-storytelling digital-marketing marketing-insights seo-organic-search">
            <a class="" href="#">Content Marketing &amp; Storytelling</a>
          </li>
          <li class="digital-marketing marketing-insights outsourced-marketing">
            <a class="" href="#">Digital Marketing</a>
          </li>
          <li class="company-culture content-marketing-storytelling eos marketing-insights">
            <a class="" href="#">EOS</a>
          </li>
          <li class="branding case-studies digital-marketing fractional-cmo fractional-cmo-case-studies marketing-strategy social-media">
            <a class="" href="#">Fractional CMO</a>
          </li>
          <li class="fractional-cmo marketing-insights marketing-strategy outsourced-marketing">
            <a class="" href="#">Fractional CMO</a>
          </li>
          <li class="insights">
            <a class="" href="#">Insights</a>
          </li>
          <li class="marketing-analytics marketing-insights outsourced-marketing">
            <a class="" href="#">Marketing Analytics</a>
          </li>
          <li class="digital-marketing marketing-analytics marketing-automation marketing-insights marketing-strategy">
            <a class="" href="#">Marketing Automation</a>
          </li>
          <li class="business-strategy marketing-insights marketing-planning">
            <a class="" href="#">Marketing Planning</a>
          </li>
          <li class="branding case-studies content-marketing-storytelling marketing-analytics marketing-services outsourced-marketing sem-paid-advertising seo-organic-search">
            <a class="" href="#">Marketing Services</a>
          </li>
          <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
            <a class="" href="#">Marketing Strategy</a>
          </li>
          <li class="company-culture marketing-insights marketing-strategy outsourced-marketing">
            <a class="" href="#">Outsourced Marketing</a>
          </li>
          <li class="digital-marketing marketing-insights outsourced-marketing sem-paid-advertising seo-organic-search">
            <a class="" href="#">SEM &amp; Paid Advertising</a>
          </li>
          <li class="branding content-marketing-storytelling digital-marketing marketing-insights seo-organic-search">
            <a class="" href="#">SEO &amp; Organic Search</a>
          </li>
          <li class="content-marketing-storytelling digital-marketing marketing-insights social-media">
            <a class="" href="#">Social Media</a>
          </li>
        </ul>
      </li>
    </ul>
    Login or Signup to reply.
  2. Instead of pre-rendering everything in html, consider using DOM manipulation functions like insertAdjacentHTML.

    Add the filtering and rendering logic inside of a click event listener and attach the listener to the Resources. Consider using Event Delegation instead of attaching the event listeners to each one of the items.

    script.js

    const topics = [
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Content Marketing & Story Telling',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Digital Marketing',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'EOS',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Fractional CMO',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Fractional CMO',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Insights',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Marketing Analytics',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Marketing Automation',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Marketing Planning',
          link: '#',
        },
        {
          className: 'class-name',
          category: 'some-category',
          text: 'Marketing Services',
          link: '#',
        },
      ];
    
      // Filter the topics based on your condition;
      const filteredTopics = topics.filter(
        (topic) => topic.category === 'some-category'
      );
    
      // Generate markup for the filtered list
      const markup = generateMarkupTopics(filteredTopics);
    
      // Attach the generated markup to an element in the html
      const topicsContainer = document.querySelector('.topics-container');
      topicsContainer.insertAdjacentHTML('afterbegin', markup);
    
      const generateMarkupTopics = function (list) {
        return list.map(generateMarkupTopicItem).join(' ');
      };
    
      const generateMarkupTopicItem = function (item) {
        return `
            <li class=${item.className}>
                  <a href="${item.link}">${item.text}</a>
                </li>
             `;
      };
    
    <body>
    ....
    ....
    <ul class="filter-topics"></ul>
    </body>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search