Simulate server-side type-ahead search

This commit is contained in:
2026-06-04 18:35:21 +02:00
parent c5492ff8df
commit ab17a5e1fa
+21 -10
View File
@@ -80,7 +80,7 @@
<article class="sg-card sg-large-table" data-component="large-table" role="table" aria-label="Beispiel Large Table">
<div class="sg-card-segment sg-card-segment--header sg-card-segment--darkblue sg-large-table__title-segment" data-component-part="large-table-header">
<div class="sg-strong">Large Table</div>
<form class="sg-search-field-row" data-component="search-field" data-large-table-search-form>
<span class="sg-search-field-row" data-component="search-field">
<span class="sg-input-single-line-wrap" data-has-value="false" data-component="single-line-input" data-component-state="inactive-selectable">
<input
class="sg-interaction-element sg-input-single-line sg-search-field-input sg-input-single-line--inactive-selectable sg-form-inactive-selectable"
@@ -91,7 +91,7 @@
>
<button class="sg-input-clear-button" type="button" aria-label="Eingabe löschen">×</button>
</span>
</form>
</span>
</div>
<div class="sg-card-segment sg-card-segment--body sg-card-segment--white sg-large-table__row sg-large-table__row--header" role="row" data-component-part="large-table-header-row">
@@ -224,11 +224,12 @@
const searchInput = table.querySelector('[data-large-table-search]');
const searchFieldWrap = table.querySelector('[data-component="single-line-input"]');
const searchClearButton = table.querySelector('.sg-input-clear-button');
const searchForm = table.querySelector('[data-large-table-search-form]');
let searchTimer = null;
const state = {
columnIndex: 0,
direction: 'ascending',
query: '',
loading: false,
};
function setHeaderState(activeIndex, direction) {
@@ -280,6 +281,7 @@
}
function renderRows() {
table.setAttribute('aria-busy', state.loading ? 'true' : 'false');
const sortedRows = rows.slice().sort((leftRow, rightRow) => {
const leftCell = leftRow.querySelectorAll('[role="cell"]')[state.columnIndex];
const rightCell = rightRow.querySelectorAll('[role="cell"]')[state.columnIndex];
@@ -320,21 +322,30 @@
if (searchFieldWrap) {
searchFieldWrap.setAttribute('data-has-value', searchInput.value ? 'true' : 'false');
}
});
}
if (searchForm && searchInput) {
searchForm.addEventListener('submit', (event) => {
event.preventDefault();
state.query = searchInput.value.trim().toLowerCase();
state.loading = true;
renderRows();
if (searchTimer) {
window.clearTimeout(searchTimer);
}
searchTimer = window.setTimeout(() => {
state.query = searchInput.value.trim().toLowerCase();
state.loading = false;
renderRows();
}, 250);
});
}
if (searchClearButton && searchInput) {
searchClearButton.addEventListener('click', () => {
if (searchTimer) {
window.clearTimeout(searchTimer);
searchTimer = null;
}
searchInput.value = '';
state.query = '';
state.loading = false;
if (searchFieldWrap) {
searchFieldWrap.setAttribute('data-has-value', 'false');
}