Skip to content
Version:

Master Page ​

Component nesting ​

  • Vertical Layout
    • Filter Panel
      • Inputs
      • Additional filter action buttons
    • Toolbar (connected to Filter Panel and Grid)
      • Additional grid batch actions
    • Grid

Implementation ​

vue
<template>
  <MateVerticalLayout theme="padding spacing" style="align-items: stretch;">
    <MateFilterPanel @search-click="onSearch" @reset-click="onReset">
      <MateTextField label="Username" :value="usernameFilter" @value-changed="usernameFilter = $event.detail.value" />
      <MateTextField label="Vorname" :value="prenameFilter" @value-changed="prenameFilter = $event.detail.value" />
      <MateTextField label="Nachname" :value="familyNameFilter" @value-changed="familyNameFilter = $event.detail.value" />
    </MateFilterPanel>
    <hr />
    <MateToolbar title-text="Users">
      <MateButton @click="onDelete">Loeschen</MateButton>
    </MateToolbar>
    <MateGrid ref="grid" :items="items" theme="column-borders" style="flex-grow: 1;"
      :row-provider="rowProvider"
      :primary-action-column-provider="primaryActionColumnProvider">
      <MateGridSortColumn header="Username" path="username" :resizable="true" />
      <MateGridSortColumn header="Geburtstag" :resizable="true" :renderer="birthdateRenderer" />
      <MateGridSortColumn header="Geschlecht" :resizable="true" :renderer="genderRenderer" />
      <MateGridSortColumn header="Vorname" path="prename" :resizable="true" />
      <MateGridSortColumn header="Nachname" path="familyName" />
    </MateGrid>
  </MateVerticalLayout>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { MateFilterPanel } from '@mate-vue/filter-panel';
import { MateToolbar } from '@mate-vue/toolbar';
import { MateTextField } from '@mate-vue/text-field';
import { MateButton } from '@mate-vue/button';
import { MateGrid, MateGridSortColumn } from '@mate-vue/grid';

const grid = ref(null);
const items = ref([...allItems]);
const usernameFilter = ref('');
const prenameFilter = ref('');
const familyNameFilter = ref('');

const rowProvider = (item) => {
  if (!item) return {};
  return { disabled: item.username.startsWith('s'), hasDetails: item.gender === DummyGender.Female };
};

const primaryActionColumnProvider = (item) => {
  if (!item) return {};
  return {
    tooltipText: 'Aktionen fuer ' + item.username,
    children: [
      { text: 'Bearbeiten' },
      { text: 'Loeschen', disabled: true, tooltipText: 'Du kannst dieses Element nicht loeschen' },
      { text: 'Children', children: [
        { text: 'Test', tooltipText: 'My tooltip' },
        { text: 'Male', hidden: item.gender !== DummyGender.Male }
      ]}
    ]
  };
};

const birthdateRenderer = (item) =>
  item.birthdate.toLocaleString('de-DE', { year: 'numeric', month: '2-digit', day: '2-digit' });

const genderRenderer = (item) =>
  item.gender === DummyGender.Female ? 'Weiblich' : item.gender === DummyGender.Male ? 'Maennlich' : 'Divers';

const arrayFilter = (value, property) => (item) => {
  if (!value || value.length < 1) return true;
  const itemVal = item[property];
  if (!itemVal || itemVal.length < 1) return false;
  return itemVal.toLowerCase().includes(value.toLowerCase());
};

const onSearch = () => {
  items.value = allItems
    .filter(arrayFilter(usernameFilter.value, 'username'))
    .filter(arrayFilter(prenameFilter.value, 'prename'))
    .filter(arrayFilter(familyNameFilter.value, 'familyName'));
};

const onReset = () => {
  usernameFilter.value = '';
  prenameFilter.value = '';
  familyNameFilter.value = '';
  items.value = [...allItems];
};

const onDelete = () => {
  const g = grid.value;
  if (g?.selectedItems) {
    g.selectedItems.forEach((item) => allItems.splice(allItems.indexOf(item), 1));
    items.value = [...allItems];
  }
};
</script>

For lazy loading examples see Grid component examples.