Skip to content

Comments

Add search/filter functionality for channels and programs#92

Closed
Copilot wants to merge 4 commits intodevfrom
copilot/add-search-filter-bar
Closed

Add search/filter functionality for channels and programs#92
Copilot wants to merge 4 commits intodevfrom
copilot/add-search-filter-bar

Conversation

Copy link
Contributor

Copilot AI commented Feb 16, 2026

Implements real-time search across channel names, program titles, and descriptions with visual feedback and accessibility support.

Changes

UI Components (templates/guide.html)

  • Search bar positioned between fixed time header and guide grid
  • Input field with clear button (✕) and result count display
  • ARIA labels for screen reader support

Search Logic (templates/guide.html)

  • 250ms debounced input with 2-character minimum
  • Filters guide rows by matching search term against channel names, program titles, and descriptions
  • Highlights matching text using safe DOM manipulation (createElement/createTextNode) to prevent XSS
  • Escape key clears search, result count updates dynamically

Styling (static/css/base.css)

  • CSS variables for theme integration (dark/light modes)
  • Sticky positioning at top with z-index 100
  • Highlight styles: .search-highlight with theme-aware backgrounds
  • Hidden state: .guide-row.hidden-by-search { display: none !important; }

Mobile Support (static/css/mobile.css)

  • 16px font size prevents iOS zoom on focus
  • Adjusted padding for viewport < 900px

Example

// Safe text highlighting - no innerHTML with user input
const parts = text.split(regex);
element.textContent = '';
parts.forEach((part, i) => {
  if (i % 2 === 0) {
    element.appendChild(document.createTextNode(part));
  } else {
    const span = document.createElement('span');
    span.className = 'search-highlight';
    span.textContent = part;
    element.appendChild(span);
  }
});

Screenshots

Dark theme with search bar:
Dark theme

Search with results:
Search active

Light theme:
Light theme

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • iptv.lan
    • Triggering command: /usr/bin/python3 python3 app.py (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Issue #2: Guide UX Improvements - Search/Filter Implementation

Objective

Add a search/filter box for channels and programs with real-time filtering and result count display.

Requirements

1. UI Components (templates/guide.html)

Add search bar before the guide grid (after line 69, before line 72 <div class="guide-outer">):

<!-- Search/Filter Bar -->
<div class="search-bar" id="searchBar">
  <div class="search-container">
    <input type="text" 
           id="searchInput" 
           class="search-input" 
           placeholder="Search channels or programs..."
           autocomplete="off"
           aria-label="Search channels or programs">
    <button type="button" 
            id="clearSearch" 
            class="clear-search" 
            aria-label="Clear search"
            style="display: none;"></button>
  </div>
  <div class="search-results" id="searchResults" style="display: none;">
    <span id="resultCount">0</span> results found
  </div>
</div>

2. CSS Styling (static/css/base.css)

Add after the guide grid styles (around line 127):

/* Search/Filter Bar */
.search-bar {
  padding: 12px 16px;
  background: var(--search-bg, rgba(0, 0, 0, 0.2));
  border-bottom: 1px solid var(--search-border, rgba(255, 255, 255, 0.1));
  position: sticky;
  top: 0;
  z-index: 100;
}

.search-container {
  position: relative;
  max-width: 600px;
  margin: 0 auto;
}

.search-input {
  width: 100%;
  padding: 10px 40px 10px 16px;
  font-size: 15px;
  border: 2px solid var(--search-input-border, rgba(255, 255, 255, 0.2));
  border-radius: 24px;
  background: var(--search-input-bg, rgba(255, 255, 255, 0.1));
  color: var(--search-input-color, inherit);
  transition: all 0.2s ease;
  box-sizing: border-box;
}

.search-input:focus {
  outline: none;
  border-color: var(--primary-color, #0af);
  background: var(--search-input-bg-focus, rgba(255, 255, 255, 0.15));
  box-shadow: 0 0 0 3px var(--search-focus-shadow, rgba(0, 170, 255, 0.1));
}

.search-input::placeholder {
  color: var(--search-placeholder, rgba(255, 255, 255, 0.4));
}

.clear-search {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  color: var(--search-clear-color, rgba(255, 255, 255, 0.6));
  font-size: 20px;
  cursor: pointer;
  padding: 4px 8px;
  line-height: 1;
  transition: color 0.2s ease;
}

.clear-search:hover {
  color: var(--search-clear-hover, #fff);
}

.search-results {
  text-align: center;
  margin-top: 8px;
  font-size: 13px;
  color: var(--search-results-color, rgba(255, 255, 255, 0.7));
}

.search-results #resultCount {
  font-weight: 600;
  color: var(--primary-color, #0af);
}

/* Hidden state for filtered rows */
.guide-row.hidden-by-search {
  display: none !important;
}

/* Highlight matching text */
.search-highlight {
  background: var(--search-highlight-bg, rgba(255, 255, 0, 0.3));
  color: var(--search-highlight-color, inherit);
  font-weight: 600;
  border-radius: 2px;
  padding: 0 2px;
}

3. JavaScript Functionality (templates/guide.html)

Add a new <script> block after the auto-scroll script (after line 548):

<script>
// Search/Filter Functionality
document.addEventListener('DOMContentLoaded', () => {
  const searchInput = document.getElementById('searchInput');
  const clearBtn = document.getElementById('clearSearch');
  const resultsDiv = document.getElementById('searchResults');
  const resultCountSpan = document.getElementById('resultCount');
  const guideRows = Array.from(document.querySelectorAll('.guide-row:not(.hide-in-grid)'));
  
  let searchTimeout = null;
  
  function clearHighlights() {
    document.querySelectorAll('.search-highlight').forEach(el => {
      const parent = el.parentNode;
      parent.replaceChild(document.createTextNode(el.textContent), el);
      parent.normalize();
    });
  }
  
  function highlightText(element, searchTerm) {
    if (!searchTerm || searchTerm.length < 2) return;
    
    const text = element.textContent;
    const regex = new RegExp(`(${escapeRegex(searchTerm)})`, 'gi');
    
    if (!regex.test(text)) return;
    
    const html = text.replace(regex, '<span class="search-highlight">$1</span>');
    element.innerHTML = html;
  }
  
  function escapeRegex(string) {
    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  }
  
  function performSearch(searchTerm) {
    clearHighlights();
    
    searchTerm = searchTerm.trim().toLowerCase();
    
    // Show/hide clear button
    clearBtn.style.display = searchTerm ? 'block' : 'none';
    
    if (!searchTerm || searchTerm.length < 2) {
      // Show all rows
      guideRows.forEach(row => row.classList.remove('hidden-by-search'));
      resultsDiv.style.display = 'none';
      return;
    }
    
    let visibleCount = 0;
    
    guideRows.forEach(row => {
      const chanName = row.querySelector('.chan-name span');
      const channelText = chanName ? chanName.textCon...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

Copilot AI and others added 3 commits February 16, 2026 20:26
… support

Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com>
Copilot AI changed the title [WIP] Add search/filter box for channels and programs Add search/filter functionality for channels and programs Feb 16, 2026
Copilot AI requested a review from thehack904 February 16, 2026 20:32
Copilot stopped work on behalf of thehack904 due to an error February 16, 2026 20:36
@thehack904
Copy link
Owner

I'm not ready for this to be an improvement. It just doesn't look/feel correct for the project at this time.

@thehack904 thehack904 closed this Feb 16, 2026
@thehack904 thehack904 deleted the copilot/add-search-filter-bar branch February 16, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants