<div class="table">
    <div class="table__inner">
        <table>
            <tbody>
                <tr>
                    <th scope="row">Titel</th>
                    <td>Seminar zur Jahresmitte</td>
                    <td>Seminar zum Jahreswechsel</td>
                </tr>
                <tr>
                    <th scope="row">Kurzbeschreibung</th>
                    <td>Auch in diesem Jahr möchten wir Sie wie gewohnt ausführlich und praxisnah über wichtige Änderungen im Bereich der Sozialversicherung informieren.</td>
                    <td>Auch in diesem Jahr möchten wir Sie wie gewohnt ausführlich und praxisnah über wichtige Änderungen im Bereich der Sozialversicherung informieren.</td>
                </tr>
                <tr>
                    <th scope="row">Veranstaltungsort</th>
                    <td>hkk Hauptgeschäftsstelle Bremen (Innenstadt)</td>
                    <td>hkk Hauptgeschäftsstelle Bremen (Innenstadt)</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  tbody\n    tr\n      th(scope='row') Titel\n      td Seminar zur Jahresmitte\n      td Seminar zum Jahreswechsel\n    tr\n      th(scope='row') Kurzbeschreibung\n      td Auch in diesem Jahr möchten wir Sie wie gewohnt ausführlich und praxisnah über wichtige Änderungen im Bereich der Sozialversicherung informieren.\n      td Auch in diesem Jahr möchten wir Sie wie gewohnt ausführlich und praxisnah über wichtige Änderungen im Bereich der Sozialversicherung informieren.\n    tr\n      th(scope='row') Veranstaltungsort\n      td hkk Hauptgeschäftsstelle Bremen (Innenstadt)\n      td hkk Hauptgeschäftsstelle Bremen (Innenstadt)\n"
}
  • Content:
    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));
    
  • URL: /components/raw/table/table-filter-bbnr.js
  • Filesystem Path: src/components/atoms/table/table-filter-bbnr.js
  • Size: 3.4 KB
  • Content:
    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));
    
  • URL: /components/raw/table/table-filter-generic.js
  • Filesystem Path: src/components/atoms/table/table-filter-generic.js
  • Size: 2.7 KB
  • Content:
    .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;
        }
      }
    }
    
  • URL: /components/raw/table/table.scss
  • Filesystem Path: src/components/atoms/table/table.scss
  • Size: 2.6 KB

There are no notes for this item.