Files
jandl-taskmanager-app/app/src/plugins/tm@_components/z-autocomplete.vue
T
2023-04-05 17:56:02 +02:00

144 lines
2.6 KiB
Vue

<template>
<div class="wrapper">
<v-text-field
:label="label"
variant="solo"
v-model="search"
@keydown.enter="optionSelected()"
@keydown.tab="optionSelected()"
:class="{ error: validations?.$errors?.length }"
:hint="
validations?.$errors
? errorUtils.parseErrors(validations?.$errors)
: null
"
/>
<div class="suggestion" v-if="suggestion">
<span class="hidden-part">{{ suggestion._suggestionHiddenPart }}</span>
<span>{{ suggestion._suggestionShownPart }}</span>
</div>
</div>
</template>
<script>
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
export default {
emits: ['option-selected'],
props: {
label: {
type: String,
required: false,
},
options: {
type: Array,
required: true
},
validations: {
type: Object || null,
required: false
},
clearOnSubmit: {
type: Boolean,
required: false,
default: () => true
},
value: {
required: false
}
},
data() {
return {
errorUtils,
search: ''
}
},
computed: {
suggestion() {
const normalizedSearch = this._normalize(this.search)
if (!normalizedSearch.length || !this.options.length)
return null
const filteredOptions = this.options.filter(option => {
const normalizedValue = this._normalize(option.value)
return normalizedValue.includes(normalizedSearch)
// return normalizedSearch == normalizedValue.slice(0, normalizedSearch.length)
})
if (!filteredOptions[0])
return null
// const s = filteredOptions[0].value.split(' ')
// filteredOptions[0].value = s[1] + ' ' + s[0]
const suggestion = {
...filteredOptions[0],
_suggestionHiddenPart: filteredOptions[0].value.slice(0, normalizedSearch.length),
_suggestionShownPart: filteredOptions[0].value.slice(normalizedSearch.length, filteredOptions[0].value.length)
}
return suggestion
}
},
mounted() {
if (this.value)
this.search = this.value
},
methods: {
optionSelected() {
if (!this.suggestion)
return
this.$emit('option-selected', this.suggestion)
if (this.clearOnSubmit)
this.search = ''
else
this.search = this.suggestion.value
},
_normalize(value) {
if (!value) return ''
return value
.trim()
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
}
},
watch: {
value(value) {
this.search = value
}
}
}
</script>
<style lang="sass" scoped>
.wrapper
position: relative
.suggestion
position: absolute
top: 27px
left: 15.5px
opacity: 0.5
letter-spacing: 0.009375em
.hidden-part
opacity: 0
</style>