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
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(); |
|
} |
|
}, |
|
}, |
|
};
|
|
|