Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 62 additions & 5 deletions static/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -613,11 +613,8 @@ if (clearFiltersBtn) {
resultsEmptyEl.style.display = "block";
resultsGrid.style.display = "none";
resultsEmptyEl.style.display = "block";
showSearchInput(false); // Hide search when no results
if (message && emptyMessageEl) emptyMessageEl.textContent = message;
if (!projects || projects.length === 0) { //if no projects returned from api, show the "no results" message and hide the grid
resultsGrid.style.display = "none";
resultsEmptyEl.style.display = "block";
if (message && emptyMessageEl) emptyMessageEl.textContent = message; //if api sent back a message (e.g. "no projects found matching your criteria"), show that
resultsSection.scrollIntoView({ behavior: "smooth" });
return;
}
Expand All @@ -630,6 +627,10 @@ if (clearFiltersBtn) {
resultsGrid.appendChild(buildProjectCard(project));
});

// Show search input and setup filter (only once)
showSearchInput(true);
if (!searchInput) setupFilter();

resultsSection.scrollIntoView({ behavior: "smooth" });
}

Expand Down Expand Up @@ -703,6 +704,62 @@ if (clearFiltersBtn) {
return text.length > maxLength ? text.slice(0, maxLength) + "..." : text;
}

// ----------------------------------------------------------
// Filter projects based on search input (title, description, AND skills)
// ----------------------------------------------------------
var searchInput = null;
var currentProjects = [];

function setupFilter() {
searchInput = document.getElementById("results-search");
if (!searchInput) return;

searchInput.addEventListener("input", function (e) {
var searchTerm = e.target.value.trim().toLowerCase();
var cards = resultsGrid.querySelectorAll(".project-card");

cards.forEach(function (card) {
// Get title and description
var title = card.querySelector(".project-card-title")?.textContent.toLowerCase() || "";
var desc = card.querySelector(".project-card-desc")?.textContent.toLowerCase() || "";

// Get all skill/tag text from project-tag elements
var tags = card.querySelectorAll(".project-tag");
var tagTexts = "";
tags.forEach(function(tag) {
tagTexts += tag.textContent.toLowerCase() + " ";
});

// Combine all searchable text
var searchableText = title + " " + desc + " " + tagTexts;

// Check if search term matches ANY content
if (searchTerm === "" || searchableText.includes(searchTerm)) {
card.style.display = "";
} else {
card.style.display = "none";
}
});
});
}

function showSearchInput(show) {
var wrap = document.getElementById("results-search-wrap");
if (wrap) {
wrap.style.display = show ? "block" : "none";
if (show && searchInput) {
searchInput.value = "";
// Reset any hidden cards when showing search
if (resultsGrid) {
var cards = resultsGrid.querySelectorAll(".project-card");
cards.forEach(function(card) {
card.style.display = "";
});
}
}
}
}

} // end isIndexPage


Expand Down Expand Up @@ -954,4 +1011,4 @@ function scrollToTop() {
if (scrollTopBtn) {
window.addEventListener('scroll', handleScroll);
scrollTopBtn.addEventListener('click', scrollToTop);
}
}
39 changes: 39 additions & 0 deletions static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2845,4 +2845,43 @@ select:focus {
flex: 1;
white-space: pre;
color: #e6edf3;
}
/* ---- Results Search Input --------------------------------- */
.results-search-wrap {
max-width: 480px;
margin: 0 auto 32px auto;
}

.results-search-input {
width: 100%;
padding: 12px 18px;
font-family: var(--font-body);
font-size: 0.95rem;
border: 1.5px solid var(--border);
border-radius: var(--r-full);
background: var(--white);
transition: border-color var(--t), box-shadow var(--t);
}

.results-search-input:focus {
outline: none;
border-color: var(--indigo-500);
box-shadow: 0 0 0 3px rgba(79, 110, 247, 0.12);
}

.results-search-input::placeholder {
color: var(--gray-400);
}

/* ---- Accessibility ----------------------------------------- */
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
Loading
Loading