@econnect/webcomponents-library
Documentation
Styleguide
Documentation
Styleguide
  • Getting Started

    • Installation
    • Patch Notes
    • Styleguide
  • Styling

    • e-connect colors
  • UI Components

    • Form

      • Search Field
      • Form Field
      • Forms
    • Filter

      • Filter
      • Search Filter
    • Grid

      • Grid
      • Grid Row
    • Inputs

      • File Input
      • Input Checkbox
      • Input Dropdown
      • Input Date
      • Input Date Time
      • Input Date Time Local
      • Input File
      • Input Label
      • Input Multi Select
      • Input Number
      • Input Radio
      • Input Range
      • Input Select
      • Input Switch
      • Input Slider
      • Input Text
      • Input TextArea
      • Input Time
      • Input Time Range
    • Controls

      • Booleans
      • Button
      • Checkboxes
      • Date Displays
      • Dropdown Lists
      • Text Displays
    • Headers

      • e-header
    • Cards

      • e-card
    • Images

      • Icon
      • Images
      • Flag Image
      • Hamburger
    • Iframe
    • Pager
    • Settings
    • Document Validation
    • Navigation

      • Navigation
      • Navigation Menu
      • Navigation Footer
      • Navigation Button
      • Navigation Button Item
      • Navigation Search Item

Search Filter v1.0

The <e-search-filter> component is a component that can be used for .

Usage

An e-search-filter has attributes that must be provided

<e-search-filter
  filter=""
  title=""
  type=""
/>

Attributes : e-search-filter

ValueTypeOptionalDefault
titleStringno''
valueStringyes''
typeStringno''
optionsstring[][]yes[]
iconStringyes'add'

Examples

Below an interactive example of e-search-filter can be found.

example filter

Source Code

e-search-filter.vue
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { map, isEmpty } from 'lodash-es';

import { EFormFieldModel, EFormFieldOptionType } from 'types';

import EIcon from '../e-icon/e-icon.vue';
import EFormField from '../e-form-field/e-form-field.vue';

export type Props = {
  title: string;
  value?: string;
  type: string;
  options?: string[][];
  icon?: string;
};
const props = withDefaults(defineProps<Props>(), {
  value: '',
  options: () => {
    return [];
  },
  icon: 'add'
});

const emit = defineEmits<{
  (e: 'update:searchValue', value: string): void;
}>();

const { t } = useI18n({ useScope: 'global' });

const filter = computed(() => {
  return props.title;
});
const filterOptions = computed(() => {
  return map(props.options, (option: string[], index: number) => {
    const textValue = option[0];
    return {
      id: index.toString(),
      value: textValue,
      text: textValue,
      disabled: null,
      hidden: null
    } as EFormFieldOptionType;
  });
});
const filterType = computed(() => {
  switch (props.type) {
    case 'text-dropdown':
      return 'select';
    case 'date':
      return 'date';
    case 'datetime':
      return 'datetime';
    case 'timerange':
      return 'timerange';
    case 'text':
    default:
      return 'text';
  }
});
const localFilterValue = ref(props.value);
const filterModel = computed(() => {
  return {
    type: filterType.value,
    id: `input_${filter.value}`,
    value: localFilterValue.value,
    label: '',
    placeholder: t('search.filterPlaceholder'),
    required: false,
    hidden: false,
    meta: {
      nullable: false
    },
    options: filterOptions.value
  } as EFormFieldModel;
});

const isHovered = ref(false);
const iconState = computed(() => {
  const states: string[] = [];

  if (isHovered.value) {
    states.push('hovered');
  }

  if (states.length > 0) {
    return states.join('-');
  } else {
    return 'default';
  }
});

function setHovered(newValue: boolean) {
  isHovered.value = newValue;
}

function updateFilterValue(value: string, isSubmit = true) {
  localFilterValue.value = value;

  if (isSubmit && !isEmpty(value)) emit('update:searchValue', value);
}

watch(
  () => props.value,
  newValue => {
    localFilterValue.value = newValue;
  }
);
</script>

<template>
  <div
    class="e-search-filter"
    :title="`Filter: ${type} ${filter}`"
    :tabindex="0"
    @focusin="setHovered(true)"
    @focusout="setHovered(false)"
    @mouseenter="setHovered(true)"
    @mouseleave="setHovered(false)"
    @click.self="updateFilterValue(localFilterValue)"
  >
    <h3
      class="e-search-filter-title"
      :title="filter"
      @click.self="updateFilterValue(localFilterValue)"
      v-text="filter"
    />
    <e-form-field
      class="e-search-filter-input"
      :model="filterModel"
      @emit:value="updateFilterValue($event.newValue, filterType !== 'text')"
      @keyup.enter="updateFilterValue($event.target.value)"
    />

    <e-icon
      :icon="[icon]"
      :height="15"
      :width="15"
      :icon-state="iconState"
      @click.self="updateFilterValue(localFilterValue)"
    />
  </div>
</template>

<style scoped lang="scss">
.e-search-filter {
  display: flex;
  flex: 1 1 auto;
  gap: 10px;
  align-items: center;
  height: 50px;
  padding: 5px 10px;
  background-color: var(--e-grid-row-background);
  transition: all 0.3s ease-in-out;

  .e-search-filter-title {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    width: 140px;
    margin: 0;
  }

  .e-search-filter-input {
    flex: 1 1 auto;
    margin-left: 8px;
  }

  &:hover {
    cursor: pointer;
    background-color: var(--e-grid-row-hover-background);
  }
}
</style>
Last Updated:: 1/6/25, 2:32 PM
Contributors: Marcel Lommers
Prev
Filter