From 188dbfe4cfd8dc1cdc7fb68e643331b8934a0315 Mon Sep 17 00:00:00 2001 From: Doug <64031739+MishaGromovPrlmn@users.noreply.github.com> Date: Fri, 6 Nov 2026 00:19:54 -0400 Subject: [PATCH 1/2] Make Applied Filters section visible without in mobile without requiring bar to be open --- _sass/elements/_dropdown_filters.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/_sass/elements/_dropdown_filters.scss b/_sass/elements/_dropdown_filters.scss index 021ea011c6..6c52a7bc0d 100644 --- a/_sass/elements/_dropdown_filters.scss +++ b/_sass/elements/_dropdown_filters.scss @@ -267,8 +267,14 @@ a.clear-filter-tags { // flex-direction: column; } // Hide applied filter tags in collapsed mobile toolbar - .filter-tag-container { - display: none; + .filter-tag-container { + display: flex; + flex-direction: column; + padding: 0 12px 10px; + + &:empty { + display: none; + } } .scroll-lock { overflow: hidden; From b190df6422396d6dd7d6966a8129ca0e3c6d7d06 Mon Sep 17 00:00:00 2001 From: Doug <64031739+MishaGromovPrlmn@users.noreply.github.com> Date: Fri, 6 Nov 2026 00:21:31 -0400 Subject: [PATCH 2/2] Integrate search terms into the filtering system, allowing multiple search keywords to appear at once --- assets/js/current-projects.js | 149 +++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 56 deletions(-) diff --git a/assets/js/current-projects.js b/assets/js/current-projects.js index 928bdc8ee1..1616c14a58 100644 --- a/assets/js/current-projects.js +++ b/assets/js/current-projects.js @@ -352,10 +352,9 @@ function searchEventHandler(e){ else if(e.target.closest(".search-bar-mobile")) searchTerm = document.querySelector("#search-mobile").value; + const filterParams = Object.fromEntries(new URLSearchParams(window.location.search)); let tokenObj={}; - tokenObj['Search']=searchTerm; - - const filterParams = Object.fromEntries(new URLSearchParams(window.location.search)); + if (Object.keys(filterParams).length>0) { for(const [key,value] of Object.entries(filterParams)){ if (key !== 'Search'){ @@ -363,10 +362,25 @@ function searchEventHandler(e){ } } } + + const searches = filterParams.Search + ? filterParams.Search.split(',') + : []; + + if (!searches.includes(searchTerm)) { + searches.push(searchTerm); + } + //include entire array of search keywords + if (searches.length > 0) { + tokenObj['Search'] = searches; + } + let queryString = Object.keys(tokenObj).map(key => key + '=' + tokenObj[key]).join('&').replaceAll(" ","+"); window.history.replaceState(null,'',`?${queryString}`) } + + function searchEnterKeyHandler(e){ if (e.key === "Enter") { @@ -496,10 +510,24 @@ function updateCategoryCounter(filterParams){ // Calculate total selected filters across all categories (excluding Search) let totalSelected = container.reduce((sum, [,val]) => sum + val, 0); + // Add count of keywords for search filter + const searchCount = (filterParams.Search || []).filter(term => term.trim() !== '').length; + totalSelected += searchCount; + // Update each category counter – preserve existing behaviour of showing combined totals - for(const [key] of container){ - document.querySelector(`#${key}`) && (document.querySelector(`#${key}`).innerHTML = ` (${totalSelected})`); - } + //for(const [key] of container){ + //document.querySelector(`#${key}`) && (document.querySelector(`#${key}`).innerHTML = ` (${totalSelected})`); + + document.querySelectorAll('.number-of-checked-boxes').forEach(counter => { + if (counter.id !== 'counter_total') { + counter.innerHTML = totalSelected > 0 + ? ` (${totalSelected})` + : ''; + } + } + ); + + // Update the new overall filters counter in the title const totalCounterSpan = document.querySelector('#counter_total'); @@ -548,67 +576,76 @@ function updateProjectCardDisplayState(filterParams){ } } else if(key==="Search"){ - let searchTerm=value[0]; - let operators=["AND","OR","-"]; - let tokens=[]; - if(searchTerm.includes(" ")){tokens=searchTerm.split(" ");} - else{tokens[0]=searchTerm} - for (let i = 0; i < tokens.length; i++) { - let token = tokens[i]; - if (operators.includes(token)) { - let nextToken=tokens[i+1]; - if (token === "AND"){ - let searchRegex= new RegExp(nextToken,'gi'); + + //scan each keyword for search filter + for (const searchTerm of value) { + + let operators=["AND","OR","-"]; + let tokens=[]; + if(searchTerm.includes(" ")){tokens=searchTerm.split(" ");} + else{tokens[0]=searchTerm} + for (let i = 0; i < tokens.length; i++) { + let token = tokens[i]; + if (operators.includes(token)) { + let nextToken=tokens[i+1]; + if (token === "AND"){ + let searchRegex= new RegExp(nextToken,'gi'); + let noMatchDataset=0; + for(const [key,value] of Object.entries(projectCardObj)){ + if( value.filter(x => searchRegex.test(x) ).length == 0){ + noMatchDataset++; + if(noMatchDataset==5){cardsToHideContainer.push([key,projectCard.id]);} + } + } + } + else if(token === "OR"){ + let searchRegex= new RegExp(nextToken,'gi'); + let noMatchDataset=0; + for(const [key,value] of Object.entries(projectCardObj)){ + if( value.filter(x => searchRegex.test(x) ).length > 0){ + cardsToHideContainer.pop(); + projectCard.style.display = 'list-item' ; + break; + } + } + } + + i++; + } + else if(token.includes("-")){ + let searchToken=token.substr(1); + let searchRegex= new RegExp(searchToken,'gi'); let noMatchDataset=0; for(const [key,value] of Object.entries(projectCardObj)){ - if( value.filter(x => searchRegex.test(x) ).length == 0){ - noMatchDataset++; - if(noMatchDataset==5){cardsToHideContainer.push([key,projectCard.id]);} - } + if( value.filter(x => searchRegex.test(x) ).length > 0){ + + cardsToHideContainer.push([key,projectCard.id]); + + } } } - else if(token === "OR"){ - let searchRegex= new RegExp(nextToken,'gi'); + else { + let searchRegex= new RegExp(token,'gi'); let noMatchDataset=0; for(const [key,value] of Object.entries(projectCardObj)){ - if( value.filter(x => searchRegex.test(x) ).length > 0){ - cardsToHideContainer.pop(); - projectCard.style.display = 'list-item' ; + if( value.filter(x => searchRegex.test(x) ).length == 0){ + noMatchDataset++; + if(noMatchDataset==5){cardsToHideContainer.push([key,projectCard.id]);} + } + else{ + projectCard.style.display = 'list-item' ; break; } } - } - - i++; - } - else if(token.includes("-")){ - let searchToken=token.substr(1); - let searchRegex= new RegExp(searchToken,'gi'); - let noMatchDataset=0; - for(const [key,value] of Object.entries(projectCardObj)){ - if( value.filter(x => searchRegex.test(x) ).length > 0){ - - cardsToHideContainer.push([key,projectCard.id]); - - } - } + } } - else { - let searchRegex= new RegExp(token,'gi'); - let noMatchDataset=0; - for(const [key,value] of Object.entries(projectCardObj)){ - if( value.filter(x => searchRegex.test(x) ).length == 0){ - noMatchDataset++; - if(noMatchDataset==5){cardsToHideContainer.push([key,projectCard.id]);} - } - else{ - projectCard.style.display = 'list-item' ; - break; - } - } - } - } + + if (cardsToHideContainer.length > 0) { + break; + } + } } + if (cardsToHideContainer.length > 0){ cardsToHideContainer.map(item => document.getElementById(`${item[1]}`).style.display = 'none'); break;