|
45 | 45 | </button> |
46 | 46 | {% endfor %} |
47 | 47 | </div> |
| 48 | + <div id="no-results" class="no-results-message is-hidden"> |
| 49 | + Please select a tag to view items. |
| 50 | + </div> |
48 | 51 | </div> |
49 | 52 |
|
50 | 53 | <style> |
|
125 | 128 | .count-pill { background: rgba(0,0,0,0.08); padding: 1px 6px; border-radius: 10px; margin-left: 8px; font-size: 0.8em; } |
126 | 129 | .filter-btn.active .count-pill { background: rgba(255,255,255,0.2); } |
127 | 130 |
|
| 131 | + .no-results-message { |
| 132 | + margin: 20px 0; |
| 133 | + padding: 2rem; |
| 134 | + text-align: center; |
| 135 | + background: #fff9e6; /* Light amber background */ |
| 136 | + border: 1px solid #ffe58f; /* Subtle border */ |
| 137 | + border-radius: 8px; |
| 138 | + color: #856404; /* Darker amber text */ |
| 139 | + font-weight: bold; |
| 140 | + font-size: 1.1em; |
| 141 | + } |
| 142 | + /* Ensure this is at the bottom of your style block */ |
| 143 | + .is-hidden { display: none !important; } |
128 | 144 | </style> |
129 | 145 |
|
130 | 146 | <script> |
131 | | -/** |
132 | | - * 1. Initial Load: Read URL parameters and apply them |
133 | | - */ |
| 147 | +/** 1. On Load: Set state from URL and run filter **/ |
134 | 148 | document.addEventListener('DOMContentLoaded', function() { |
135 | 149 | const params = new URLSearchParams(window.location.search); |
136 | | - const urlTag = params.get('tag') || 'all'; |
137 | | - const urlQuery = params.get('q') || ''; |
| 150 | + window.currentTag = params.get('tag'); // No fallback here ensures empty if missing |
138 | 151 |
|
139 | | - // Set initial state |
140 | | - window.currentTag = urlTag; |
141 | 152 | const searchInput = document.getElementById('search-input'); |
142 | | - if (searchInput) searchInput.value = urlQuery; |
| 153 | + if (searchInput) searchInput.value = params.get('q') || ''; |
143 | 154 |
|
144 | | - // Apply filters without pushing to history again |
145 | | - window.updateFilters(false); |
| 155 | + window.updateFilters(false); // Initial run |
146 | 156 | }); |
147 | 157 |
|
148 | | -/** |
149 | | - * 2. Tag Selection Handler |
150 | | - */ |
| 158 | +/** 2. Click Handler **/ |
151 | 159 | window.applyTagFilter = function(tag) { |
152 | 160 | window.currentTag = tag; |
153 | 161 | window.updateFilters(true); |
154 | 162 | }; |
155 | 163 |
|
156 | | -/** |
157 | | - * 3. Core Filter Engine |
158 | | - * @param {boolean} updateUrl - If true, syncs state to browser address bar |
159 | | - */ |
| 164 | +/** 3. Core Logic: URL Sync + Visibility + No Results Message **/ |
160 | 165 | window.updateFilters = function(updateUrl = true) { |
161 | | - const searchInput = document.getElementById('search-input'); |
162 | | - const q = searchInput ? searchInput.value : ''; |
| 166 | + const q = document.getElementById('search-input').value || ''; |
163 | 167 | const qLower = q.toLowerCase(); |
164 | 168 |
|
165 | | - // Sync state to URL |
| 169 | + // Sync Address Bar |
166 | 170 | if (updateUrl) { |
167 | 171 | const url = new URL(window.location); |
168 | | - if (window.currentTag === 'all') { |
169 | | - url.searchParams.delete('tag'); |
170 | | - } else { |
171 | | - url.searchParams.set('tag', window.currentTag); |
172 | | - } |
173 | | - |
174 | | - if (q) { |
175 | | - url.searchParams.set('q', q); |
176 | | - } else { |
177 | | - url.searchParams.delete('q'); |
178 | | - } |
179 | | - // Update address bar without reloading |
| 172 | + window.currentTag ? url.searchParams.set('tag', window.currentTag) : url.searchParams.delete('tag'); |
| 173 | + q ? url.searchParams.set('q', q) : url.searchParams.delete('q'); |
180 | 174 | window.history.replaceState({}, '', url); |
181 | 175 | } |
182 | 176 |
|
183 | | - // Filter Items in DOM |
| 177 | + let visibleCount = 0; |
| 178 | + |
| 179 | + // Logic: Only show if a tag is active (currentTag is truthy) AND search matches |
184 | 180 | document.querySelectorAll('.filter-item').forEach(item => { |
185 | 181 | const tags = (item.dataset.tags || "").split(','); |
186 | | - const text = item.innerText.toLowerCase(); |
187 | | - |
188 | | - const matchesTag = (window.currentTag === 'all' || tags.includes(window.currentTag)); |
189 | | - const matchesSearch = text.includes(qLower); |
| 182 | + const matchesTag = (window.currentTag === 'all') || (window.currentTag && tags.includes(window.currentTag)); |
| 183 | + const matchesSearch = item.innerText.toLowerCase().includes(qLower); |
190 | 184 |
|
191 | | - item.classList.toggle('is-hidden', !(matchesTag && matchesSearch)); |
| 185 | + const isVisible = !!(matchesTag && matchesSearch); |
| 186 | + item.classList.toggle('is-hidden', !isVisible); |
| 187 | + if (isVisible) visibleCount++; |
192 | 188 | }); |
193 | 189 |
|
194 | | - // Update Button UI States |
| 190 | + // Handle No Results Message |
| 191 | + const noResultsEl = document.getElementById('no-results'); |
| 192 | + if (noResultsEl) { |
| 193 | + noResultsEl.classList.toggle('is-hidden', visibleCount > 0); |
| 194 | + noResultsEl.innerText = !window.currentTag ? "Please select a tag to view items." : "No items match your criteria."; |
| 195 | + } |
| 196 | + |
| 197 | + // Sync Button UI |
195 | 198 | document.querySelectorAll('.filter-btn').forEach(btn => { |
196 | | - // Extract the tag name from the onclick attribute: applyTagFilter('tag-name') |
197 | | - const onclickAttr = btn.getAttribute('onclick') || ""; |
198 | | - const match = onclickAttr.match(/'([^']+)'/); |
199 | | - if (match) { |
200 | | - const btnTag = match[1]; |
201 | | - btn.classList.toggle('active', btnTag === window.currentTag); |
202 | | - } |
| 199 | + const btnTag = btn.getAttribute('onclick').match(/'([^']+)'/)[1]; |
| 200 | + btn.classList.toggle('active', btnTag === window.currentTag); |
203 | 201 | }); |
204 | 202 | }; |
205 | 203 |
|
206 | | -/** |
207 | | - * 4. Reset Handler |
208 | | - */ |
| 204 | +/** 4. Reset **/ |
209 | 205 | window.resetFilters = function() { |
210 | | - const searchInput = document.getElementById('search-input'); |
211 | | - if (searchInput) searchInput.value = ''; |
| 206 | + document.getElementById('search-input').value = ''; |
212 | 207 | window.applyTagFilter('all'); |
213 | 208 | }; |
214 | 209 | </script> |
0 commit comments