Simulate server-side type-ahead search
This commit is contained in:
@@ -80,7 +80,7 @@
|
|||||||
<article class="sg-card sg-large-table" data-component="large-table" role="table" aria-label="Beispiel Large Table">
|
<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-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>
|
<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">
|
<span class="sg-input-single-line-wrap" data-has-value="false" data-component="single-line-input" data-component-state="inactive-selectable">
|
||||||
<input
|
<input
|
||||||
class="sg-interaction-element sg-input-single-line sg-search-field-input sg-input-single-line--inactive-selectable sg-form-inactive-selectable"
|
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>
|
<button class="sg-input-clear-button" type="button" aria-label="Eingabe löschen">×</button>
|
||||||
</span>
|
</span>
|
||||||
</form>
|
</span>
|
||||||
</div>
|
</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">
|
<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 searchInput = table.querySelector('[data-large-table-search]');
|
||||||
const searchFieldWrap = table.querySelector('[data-component="single-line-input"]');
|
const searchFieldWrap = table.querySelector('[data-component="single-line-input"]');
|
||||||
const searchClearButton = table.querySelector('.sg-input-clear-button');
|
const searchClearButton = table.querySelector('.sg-input-clear-button');
|
||||||
const searchForm = table.querySelector('[data-large-table-search-form]');
|
let searchTimer = null;
|
||||||
const state = {
|
const state = {
|
||||||
columnIndex: 0,
|
columnIndex: 0,
|
||||||
direction: 'ascending',
|
direction: 'ascending',
|
||||||
query: '',
|
query: '',
|
||||||
|
loading: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
function setHeaderState(activeIndex, direction) {
|
function setHeaderState(activeIndex, direction) {
|
||||||
@@ -280,6 +281,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderRows() {
|
function renderRows() {
|
||||||
|
table.setAttribute('aria-busy', state.loading ? 'true' : 'false');
|
||||||
const sortedRows = rows.slice().sort((leftRow, rightRow) => {
|
const sortedRows = rows.slice().sort((leftRow, rightRow) => {
|
||||||
const leftCell = leftRow.querySelectorAll('[role="cell"]')[state.columnIndex];
|
const leftCell = leftRow.querySelectorAll('[role="cell"]')[state.columnIndex];
|
||||||
const rightCell = rightRow.querySelectorAll('[role="cell"]')[state.columnIndex];
|
const rightCell = rightRow.querySelectorAll('[role="cell"]')[state.columnIndex];
|
||||||
@@ -320,21 +322,30 @@
|
|||||||
if (searchFieldWrap) {
|
if (searchFieldWrap) {
|
||||||
searchFieldWrap.setAttribute('data-has-value', searchInput.value ? 'true' : 'false');
|
searchFieldWrap.setAttribute('data-has-value', searchInput.value ? 'true' : 'false');
|
||||||
}
|
}
|
||||||
});
|
state.loading = true;
|
||||||
|
renderRows();
|
||||||
|
|
||||||
|
if (searchTimer) {
|
||||||
|
window.clearTimeout(searchTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchForm && searchInput) {
|
searchTimer = window.setTimeout(() => {
|
||||||
searchForm.addEventListener('submit', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
state.query = searchInput.value.trim().toLowerCase();
|
state.query = searchInput.value.trim().toLowerCase();
|
||||||
|
state.loading = false;
|
||||||
renderRows();
|
renderRows();
|
||||||
|
}, 250);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchClearButton && searchInput) {
|
if (searchClearButton && searchInput) {
|
||||||
searchClearButton.addEventListener('click', () => {
|
searchClearButton.addEventListener('click', () => {
|
||||||
|
if (searchTimer) {
|
||||||
|
window.clearTimeout(searchTimer);
|
||||||
|
searchTimer = null;
|
||||||
|
}
|
||||||
searchInput.value = '';
|
searchInput.value = '';
|
||||||
state.query = '';
|
state.query = '';
|
||||||
|
state.loading = false;
|
||||||
if (searchFieldWrap) {
|
if (searchFieldWrap) {
|
||||||
searchFieldWrap.setAttribute('data-has-value', 'false');
|
searchFieldWrap.setAttribute('data-has-value', 'false');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user