skip to Main Content

Currently Im struggling with html, css and js code amd I have no idea how to make it working properly. Partially my requirements are covered but not as supposed.

My requirements:

  • Buttons with global filters, after clicking one of them filters are applied for all elements with class document new/removed/changed.
  • Unclicking button, removes filter
  • Button with local filters applicable only in div id area

Current issues:

  • Button highlight working only for global button
  • global filters don’t work
  • sometimes I have to press button twice till filter will be applicable
let activeFilter = null;

function toggleFilter(filter, containerId) {
  const filterButton = document.querySelector(`.filter-button[data-filter="${filter}"]`);
  const container = containerId ? document.getElementById(containerId) : document;

  if (!containerId || activeFilter === filter) {
    filterButton.classList.remove('active');
    activeFilter = null;
    showAllDocuments(container);
  } else {
    if (activeFilter) {
      const activeFilterButton = document.querySelector(`.filter-button[data-filter="${activeFilter}"]`);
      activeFilterButton.classList.remove('active');
    }

    filterButton.classList.add('active');
    activeFilter = filter;
    filterDocuments(container);
  }
}

function showAllDocuments(container) {
  const documents = container.querySelectorAll('.document');
  documents.forEach(doc => doc.classList.remove('hide'));
}

function filterDocuments(container) {
  const documents = container.querySelectorAll('.document');
  documents.forEach(doc => {
    const docClass = doc.classList[1];
    if (docClass === activeFilter || activeFilter === null) {
      doc.classList.remove('hide');
    } else {
      doc.classList.add('hide');
    }
  });
}
.filter-button {
  padding: 10px;
  margin: 5px;
  cursor: pointer;
}

.active {
  border: 2px solid black;
}

.document {
  margin: 10px;
  padding: 10px;
  border: 1px solid #ddd;
}

.new.hide,
.change.hide,
.removed.hide {
  display: none;
}
<div class="container">
  <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '')">Document New global</button>
  <button class="filter-button" data-filter="change" onclick="toggleFilter('change' ,'')">Document Change global</button>
  <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '')">Document Removed global</button>

  <div id="1">
    <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '1')">Document New local</button>
    <button class="filter-button" data-filter="change" onclick="toggleFilter('change', '1')">Document Change local</button>
    <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '1')">Document Removed local</button>
    <div class="document new">Document 1 (New)</div>
    <div class="document change">Document 2 (Change)</div>
    <div class="document removed">Document 3 (Removed)</div>
  </div>

  <div id="2">
    <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '2')">Document New local</button>
    <button class="filter-button" data-filter="change" onclick="toggleFilter('change', '2')">Document Change local</button>
    <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '2')">Document Removed local</button>
    <div class="document new">Document 1 (New)</div>
    <div class="document change">Document 2 (Change)</div>
    <div class="document removed">Document 3 (Removed)</div>
  </div>

  <div id="3">
    <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '3')">Document New local</button>
    <button class="filter-button" data-filter="change" onclick="toggleFilter('change', '3')">Document Change local</button>
    <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '3')">Document Removed local</button>
    <div class="document new">Document 1 (New)</div>
    <div class="document change">Document 2 (Change)</div>
    <div class="document removed">Document 3 (Removed)</div>
  </div>
</div>

2

Answers


  1. Chosen as BEST ANSWER

    Finally I've developed code working almost as was suppose. Maybe there is a small issue with button highlighting but I can take it as is :)

    let lastFilterType = '';
      let lastDivId = '';
    
      function toggleFilter(filterType, divId) {
        const containers = divId === '' ? document.querySelectorAll('.document') : document.getElementById(divId).querySelectorAll('.document');
        const buttons = document.querySelectorAll('.filter-button');
    
        if (lastFilterType === filterType && divId === lastDivId) {
          containers.forEach(document => {
            document.style.display = 'block';
          });
          buttons.forEach(button => {
            button.style.backgroundColor = '';
          });
          lastFilterType = '';
        } else {
          lastFilterType = filterType;
          lastDivId = divId;
    
          containers.forEach(document => {
            const documentClassList = document.classList;
            document.style.display = filterType === '' || documentClassList.contains(filterType) ? 'block' : 'none';
          });
    
          buttons.forEach(button => {
            const dataFilter = button.getAttribute('data-filter');
            const buttonId = button.parentElement.id;
    
            if (
              (filterType === '' || filterType === dataFilter) &&
              (divId === '' || (divId === buttonId && filterType !== ''))
            ) {
              button.style.backgroundColor = 'lightblue';
            } else {
              button.style.backgroundColor = '';
            }
          });
        }
      }
            .filter-button {
                padding: 10px;
                margin: 5px;
                cursor: pointer;
            }
    
    
            .document {
                margin: 10px;
                padding: 10px;
                border: 1px solid #ddd;
            }
    <div class="container">
        <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '')">Document New global</button>
        <button class="filter-button" data-filter="change" onclick="toggleFilter('change' ,'')">Document Change global</button>
        <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '')">Document Removed global</button>
    
        <div id="1">
            <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '1')">Document New local</button>
            <button class="filter-button" data-filter="change" onclick="toggleFilter('change', '1')">Document Change local</button>
            <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '1')">Document Removed local</button>
            <div class="document new">Document 1 (New)</div>
            <div class="document change">Document 2 (Change)</div>
            <div class="document removed">Document 3 (Removed)</div>
        </div>
    
        <div id="2">
            <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '2')">Document New local</button>
            <button class="filter-button" data-filter="change" onclick="toggleFilter('change', '2')">Document Change local</button>
            <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '2')">Document Removed local</button>
            <div class="document new">Document 1 (New)</div>
            <div class="document change">Document 2 (Change)</div>
            <div class="document removed">Document 3 (Removed)</div>
        </div>
    
        <div id="3">
            <button class="filter-button" data-filter="new" onclick="toggleFilter('new', '3')">Document New local</button>
            <button class="filter-button" data-filter="change" onclick="toggleFilter('change', '3')">Document Change local</button>
            <button class="filter-button" data-filter="removed" onclick="toggleFilter('removed', '3')">Document Removed local</button>
            <div class="document new">Document 1 (New)</div>
            <div class="document change">Document 2 (Change)</div>
            <div class="document removed">Document 3 (Removed)</div>
        </div>
    </div>


  2. I optimized the toggleFilter by distinguishing between global and local filters. So it requires checking if a container ID is provided and handling the filter application accordingly. This update function should now distinguish between the global and local filters based on the containerId. If containerId is empty then it’s a global filter else it’s local.

    let activeGlobalFilter = null;
    let activeLocalFilters = {};
    
    function toggleFilter(filter, containerId) {
      const isGlobal = !containerId; // Check if containerId is not provided for global filters
      const activeFilterKey = isGlobal ? 'global' : containerId;
      let activeFilter = isGlobal ? activeGlobalFilter : activeLocalFilters[containerId];
    
      const filterButtonsSelector = isGlobal ? `.filter-button[data-filter="${filter}"]` : `#${containerId} .filter-button[data-filter="${filter}"]`;
      const filterButtons = document.querySelectorAll(filterButtonsSelector);
    
      filterButtons.forEach(filterButton => {
        if (activeFilter === filter) {
          filterButton.classList.remove('active');
          if (isGlobal) {
            activeGlobalFilter = null;
          } else {
            activeLocalFilters[containerId] = null;
          }
          showAllDocuments(containerId);
        } else {
          if (activeFilter) {
            const activeButtonsSelector = isGlobal ? `.filter-button[data-filter="${activeFilter}"]` : `#${containerId} .filter-button[data-filter="${activeFilter}"]`;
            const activeButtons = document.querySelectorAll(activeButtonsSelector);
            activeButtons.forEach(button => button.classList.remove('active'));
          }
          filterButton.classList.add('active');
          if (isGlobal) {
            activeGlobalFilter = filter;
          } else {
            activeLocalFilters[containerId] = filter;
          }
          filterDocuments(filter, containerId);
        }
      });
    }
    
    function showAllDocuments(containerId) {
      const container = containerId ? document.getElementById(containerId) : document;
      const documents = container.querySelectorAll('.document');
      documents.forEach(doc => doc.classList.remove('hide'));
    }
    
    function filterDocuments(filter, containerId) {
      const container = containerId ? document.getElementById(containerId) : document;
      const documents = container.querySelectorAll('.document');
      documents.forEach(doc => {
        if (doc.classList.contains(filter) || filter === null) {
          doc.classList.remove('hide');
        } else {
          doc.classList.add('hide');
        }
      });
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search