<div class="table table--light">
<div class="table__inner">
<table>
<thead>
<tr>
<th scope="col">Beitragssatz</th>
<th scope="col">Einnahmen</th>
</tr>
</thead>
<tbody>
<tr>
<td>14,59 Prozent</td>
<td>Beamtenbezüge<br/>Einnahmen aus Vermietung und Verpachtung<br/>Kapitalerträge</td>
</tr>
<tr>
<td>15,19 Prozent</td>
<td>Rente<br/>Pension<br/>Betriebsrente<br/>Arbeitseinkommen neben Rente oder<br/>Versorgungsbezug</td>
</tr>
</tbody>
</table>
</div>
</div>
-
//- Prepare attr object
attr = attr || {};
attr.class = classList(attr.class);
//- Alternative design?
if (light) attr.class.push('table--light');
//- Complex table
if (complex) attr.class.push('table--complex');
//- List table
if (list) attr.class.push('table--list');
//- Fixed table layout
if (fixed) attr.class.push('table--fixed');
//- BBNR filter table
if (filter && filter.type === 'bbnr') attr.class.push('js-table-filter');
//- Generic filter table
if (filter && filter.type === 'generic') {
attr.class.push('js-table-filter-generic');
attr = Object.assign(attr, {
'data-label': filter.label,
'data-placeholder': filter.placeholder,
'data-no-results-message': filter.noResultsMessage,
});
}
//- Render table
.table&attributes(attr): .table__inner
//- Header
if headline || subline
header.table__header
if headline
!= include('@headline--headline-2', {text: headline, level: 4, attr: {class: 'table__headline'}})
if subline
.table__subline #{subline}
//- Content
if content
!= renderPug(content)
{
"content": "table\n thead\n tr\n th(scope='col') Beitragssatz\n th(scope='col') Einnahmen\n tbody\n tr\n td 14,59 Prozent\n td Beamtenbezüge#[br]Einnahmen aus Vermietung und Verpachtung#[br]Kapitalerträge\n tr\n td 15,19 Prozent\n td Rente#[br]Pension#[br]Betriebsrente#[br]Arbeitseinkommen neben Rente oder#[br]Versorgungsbezug\n",
"light": true
}
import h from 'hyperscript';
import randomId from '../../../javascripts/utils/random-id';
const hkkCompanyNumber = '20013461';
export default class TableFilter {
constructor($el) {
this.$el = $el;
this.$inner = this.$el.querySelector('.table__inner');
this.$rows = this.$el.querySelectorAll('[data-filter]');
this.$tableHead = this.$el.querySelector('thead');
this.id = randomId();
this.NUMBER_FORMAT = /^[0-9]{8}$/;
this.init();
}
init() {
this.initInput();
this.initRows();
this.initEvents();
this.initTableHead();
}
initTableHead() {
this.$tableHead.classList.add('table__table-head--hidden');
}
initInput() {
// Insert filter section
this.$el.insertBefore(
h('.table__filter',
h('.form-group',
h('label.label', { for: `table-filter-${this.id}` }, 'Ansprechpartner finden'),
h('.form-group__inner',
h('input.input.input--text', {
id: `table-filter-${this.id}`,
type: 'text',
placeholder: '8-stellige Betriebsnummer',
maxLength: 8,
}),
),
),
),
this.$inner,
);
// Define inputs
this.$input = this.$el.querySelector(`#table-filter-${this.id}`);
}
initEvents() {
this.$input.addEventListener('input', () => {
if (this.NUMBER_FORMAT.test(this.$input.value)) {
this.$input.setAttribute('aria-invalid', 'false');
this.filter(this.$input.value);
} else {
this.$input.setAttribute('aria-invalid', 'true');
this.reset();
}
});
}
initRows() {
const $rows = [...this.$rows];
$rows.forEach(($row) => {
$row.classList.add('table__row--hidden');
});
}
filter(number) {
const parsedNumber = parseInt(number.slice(-3), 10);
const $rows = [...this.$rows];
$rows.forEach(($row) => {
const rangeFrom = parseInt($row.dataset.filterFrom, 10);
const rangeTo = parseInt($row.dataset.filterTo, 10);
const rowMatches = parsedNumber >= rangeFrom && parsedNumber <= rangeTo;
const fn = rowMatches ? 'remove' : 'add';
$row.classList[fn]('table__row--hidden');
});
const message = this.$inner.querySelector('.table__message');
if (message) {
message.remove();
}
if (number === hkkCompanyNumber) {
this.$message = h('p.table__message', 'Sie haben die Betriebsnummer der hkk eingegeben. Bitte geben Sie die Betriebsnummer Ihres Betriebes an.');
this.$inner.appendChild(this.$message);
this.$inner.querySelector('table').style.display = 'none';
} else if (this.$el.querySelectorAll('.table__row--hidden').length === this.$rows.length) { // No results
this.$message = h('p.table__message', 'Für diese Betriebsnummer existiert derzeit kein Ansprechpartner.');
this.$inner.appendChild(this.$message);
this.$tableHead.classList.add('table__table-head--hidden');
this.$inner.querySelector('table').style.display = 'block';
} else {
this.$tableHead.classList.remove('table__table-head--hidden');
this.$inner.querySelector('table').style.display = 'block';
}
}
reset() {
if (this.$message) this.$message.remove();
this.initRows();
this.initTableHead();
}
}
// Initialize TableFilter
document
.querySelectorAll('.js-table-filter')
.forEach($el => new TableFilter($el));
import h from 'hyperscript';
import randomId from '../../../javascripts/utils/random-id';
const createSearchIndex = $rows => $rows.map(
$row => $row
.querySelectorAll('td[data-filter]')
.map($column => $column.innerText)
.join(' ')
);
const createFilterReducer = query => (prevMatches, rowText, rowIndex) => {
const doesMatch = rowText.toLowerCase().includes(query.toLowerCase());
if (doesMatch) {
return [...prevMatches, rowIndex];
}
return prevMatches;
};
const createNoResultsMessage = message => h(
'p.table__message',
{ style: { display: 'none' } },
message
);
const createForm = ({
id,
label,
placeholder,
onChange,
}) => {
const $input = h('input.input.input--text', {
id,
type: 'text',
placeholder,
oninput: ({ target }) => onChange(target.value.trim() || null),
});
return h('.table__filter',
h('.form-group',
h('label.label', { for: id }, label),
h('.form-group__inner', $input),
),
);
};
export default class TableFilter {
constructor($el) {
this.$el = $el;
this.$inner = this.$el.querySelector('.table__inner');
this.$table = this.$el.querySelector('table');
this.$rows = this.$el.querySelectorAll('tbody tr');
this.state = {
query: null,
results: [],
};
this.init();
}
init() {
const id = randomId();
const { label, placeholder, noResultsMessage } = this.$el.dataset;
const $form = createForm({
id,
label,
placeholder,
onChange: query => this.handleFilter(query),
});
this.searchIndex = createSearchIndex(this.$rows);
this.$noResultsMessage = createNoResultsMessage(noResultsMessage);
this.$el.insertBefore($form, this.$inner);
this.$inner.appendChild(this.$noResultsMessage);
}
handleFilter(query) {
const filterReducer = createFilterReducer(query);
const results = query !== null
? this.searchIndex.reduce(filterReducer, [])
: [];
this.state = Object.assign(this.state, { query, results });
this.render();
}
render() {
const { results, query } = this.state;
const isQueryEmpty = query === null;
const hasResults = Boolean(results.length);
this.$rows.forEach(
($row, index) => {
if (isQueryEmpty || results.includes(index)) {
$row.classList.remove('table__row--hidden');
return;
}
$row.classList.add('table__row--hidden');
},
);
if (isQueryEmpty || hasResults) {
this.$noResultsMessage.style.display = 'none';
} else {
this.$noResultsMessage.style.display = null;
}
}
}
document
.querySelectorAll('.js-table-filter-generic')
.forEach($el => new TableFilter($el));
.table {
font-size: 1.5rem;
position: relative;
&::before,
&::after {
bottom: 0;
content: '';
position: absolute;
top: 0;
width: 2rem;
z-index: 2;
}
table {
border-collapse: separate;
border-spacing: 0 1px;
caption-side: bottom;
margin: 1.5rem 0;
position: relative;
width: 100%;
}
caption {
color: $color-steelgrey-xdark;
font-style: italic;
padding-top: $spacer;
text-align: left;
}
th {
background-color: $color-red;
color: #fff;
font-weight: bold;
text-align: left;
}
td {
background-color: $color-steelgrey-light;
}
th p,
td p {
margin: 0;
}
th,
td {
padding: 1rem;
vertical-align: top;
}
}
.table--light {
table {
border-collapse: collapse;
}
thead {
border-bottom: 4px solid $color-steelgrey-light;
}
thead th {
padding-top: 0;
}
tbody {
border-top: 1px solid $color-steelgrey-light;
}
th,
td {
background-color: transparent;
border-bottom: 1px solid $color-steelgrey-light;
color: inherit;
}
}
.table--complex {
&::before {
background-image: linear-gradient(to right, #fff, rgba(#fff, 0));
left: -2rem;
}
&::after {
background-image: linear-gradient(to right, rgba(#fff, 0), #fff);
right: -2rem;
}
table {
border-left: 2rem solid transparent;
border-right: 2rem solid transparent;
}
.table__inner {
margin: 0 -2rem $spacer;
}
}
.table--list {
background-color: $color-steelgrey-xlight;
.table__inner {
margin: 0;
}
.table__header {
padding: 2rem 2rem 0;
}
.table-row--disabled {
color: $color-steelgrey;
}
.table-row--disabled strong {
color: $color-steelgrey-xdark;
}
thead,
th,
td {
border-color: $color-steelgrey;
}
th:first-child,
th:last-child,
td:first-child,
td:last-child {
padding-left: 0;
}
}
.table--fixed {
table {
table-layout: fixed;
}
}
.table__inner {
overflow-x: auto;
position: relative;
z-index: 1;
}
.table__headline {
margin-bottom: 1rem;
}
.table__message {
color: $color-red;
text-align: center;
}
.table__row--hidden {
display: none;
}
.table__table-head--hidden {
display: none;
}
@include mq($from: m) {
.table {
table {
margin-bottom: 3rem;
margin-top: 0.5rem;
}
th,
td {
padding: 1.5rem;
}
}
.table--light {
tbody th {
padding-left: 0;
}
}
.table--list {
.table__inner,
.table__header {
padding: 2rem;
}
}
}
There are no notes for this item.