Search Filter
Live-Suche und Filterung einer Produktliste.
Component HTML
html
<div class="max-w-4xl mx-auto">
<h2 class="text-2xl font-bold text-gray-900 mb-6">{{title}}</h2>
<div
data-island="search-filter"
data-island-props='{"items": {{items}}}'
>
<!-- Search Filter Island rendert hier -->
</div>
</div>Island Code
javascript
// islands/search-filter.js
export default class SearchFilterIsland {
constructor(element, props = {}) {
this.element = element;
this.items = props.items || [];
this.searchTerm = '';
this.selectedCategory = 'all';
this.init();
}
init() {
this.render();
this.attachEvents();
}
get filteredItems() {
return this.items.filter(item => {
const matchesSearch = item.name.toLowerCase().includes(this.searchTerm.toLowerCase());
const matchesCategory = this.selectedCategory === 'all' || item.category === this.selectedCategory;
return matchesSearch && matchesCategory;
});
}
get categories() {
return ['all', ...new Set(this.items.map(item => item.category))];
}
render() {
const filtered = this.filteredItems;
this.element.innerHTML = `
<div class="mb-6 flex gap-4">
<input
type="text"
placeholder="Suche..."
class="search-input flex-1 px-4 py-2 border border-gray-300 rounded-lg"
value="${this.searchTerm}"
/>
<select class="category-select px-4 py-2 border border-gray-300 rounded-lg">
${this.categories.map(cat => `
<option value="${cat}" ${cat === this.selectedCategory ? 'selected' : ''}>
${cat === 'all' ? 'Alle Kategorien' : cat}
</option>
`).join('')}
</select>
</div>
<div class="text-sm text-gray-600 mb-4">
${filtered.length} von ${this.items.length} Produkten
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
${filtered.map(item => `
<div class="p-4 bg-white border border-gray-200 rounded-lg">
<h3 class="font-semibold text-gray-900">${item.name}</h3>
<p class="text-sm text-gray-600">${item.category}</p>
<p class="text-lg font-bold text-blue-600 mt-2">${item.price}</p>
</div>
`).join('')}
</div>
${filtered.length === 0 ? '<p class="text-center text-gray-500 mt-8">Keine Produkte gefunden</p>' : ''}
`;
}
attachEvents() {
this.element.querySelector('.search-input').addEventListener('input', (e) => {
this.searchTerm = e.target.value;
this.render();
this.attachEvents();
});
this.element.querySelector('.category-select').addEventListener('change', (e) => {
this.selectedCategory = e.target.value;
this.render();
this.attachEvents();
});
}
destroy() {
// Cleanup
}
}Was du lernst
- Live Search: Sofortige Filterung bei Eingabe
- Multiple Filters: Kombination von Such- und Kategorie-Filter
- Computed Values: Abgeleitete Werte (filteredItems, categories)
- Performance: useMemo/computed für optimierte Berechnungen