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
| Value | Type | Optional | Default |
|---|---|---|---|
| title | String | no | '' |
| value | String | yes | '' |
| type | String | no | '' |
| options | string[][] | yes | [] |
| icon | String | yes | '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>