You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

65 lines
1.7 KiB

export default {
template: `
<q-input
ref="qRef"
v-bind="$attrs"
v-model="inputValue"
:shadow-text="shadowText"
@keydown.tab="perform_autocomplete"
:list="id + '-datalist'"
>
<template v-for="(_, slot) in $slots" v-slot:[slot]="slotProps">
<slot :name="slot" v-bind="slotProps || {}" />
</template>
</q-input>
<datalist v-if="withDatalist" :id="id + '-datalist'">
<option v-for="option in autocomplete" :value="option"></option>
</datalist>
`,
props: {
id: String,
autocomplete: Array,
value: String,
},
data() {
return {
inputValue: this.value,
emitting: true,
};
},
watch: {
value(newValue) {
this.emitting = false;
this.inputValue = newValue;
this.$nextTick(() => (this.emitting = true));
},
inputValue(newValue) {
if (!this.emitting) return;
this.$emit("update:value", newValue);
},
},
computed: {
shadowText() {
if (!this.inputValue) return "";
const matchingOption = this.autocomplete.find((option) =>
option.toLowerCase().startsWith(this.inputValue.toLowerCase())
);
return matchingOption ? matchingOption.slice(this.inputValue.length) : "";
},
withDatalist() {
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
return isMobile && this.autocomplete && this.autocomplete.length > 0;
},
},
methods: {
updateValue() {
this.inputValue = this.value;
},
perform_autocomplete(e) {
if (this.shadowText) {
this.inputValue += this.shadowText;
e.preventDefault();
}
},
},
};