Vue code:
<template>
<div>
<v-card
color="grey darken-2"
dark
>
<v-card-text>
<v-autocomplete
spellcheck="false"
v-model="model"
:items="items"
:loading="isLoading"
:search-input.sync="search"
@change="search=''"
color="white"
hide-no-data
hide-selected
clearable
item-text="CodeAndName"
item-value="Code"
placeholder="Search stock symbols and names"
prepend-icon="mdi-account-search"
return-object
autofocus
dense
>
<template v-slot:item="{ item }">
<v-list>
<v-list-item-title class="justify-center">{{item.Code}}</v-list-item-title>
<v-list-item-subtitle>{{item.Name}}</v-list-item-subtitle>
<v-list-item-subtitle>{{item.Exchange}}</v-list-item-subtitle>
</v-list>
</template>
</v-autocomplete>
</v-card-text>
<v-divider></v-divider>
</v-card>
<Chart v-if="model" :exchangeCode="model.Exchange" :symbol="model.Code"/>
</div>
</template>
JS code:
import Chart from './GChart.vue'
export default {
name: "Search",
components: {
Chart,
},
data: () => ({
symbolsExchangesNames: [],
isLoading: false,
model: null,
search: null
}),
computed: {
items () {
return this.symbolsExchangesNames
}
},
methods: {
fetchData() {
if (this.isLoading && this.model) return
this.isLoading = true
this.model = null
this.symbolsExchangesNames = []
let hostname = window.location.hostname
fetch(`http://${hostname}/backend/search/${this.search}`)
.then(res => res.json())
.then(res => {
for(let i of res){
this.symbolsExchangesNames.push({
Code: i.Symbol,
Exchange: i.Exchange,
Name: i.Name,
CodeAndName: `${i.Symbol} ${i.Name}`
})
}
})
.catch(err => {
console.log(err)
})
.finally(() => (this.isLoading = false))
},
fetchDebounced() {
clearTimeout(this._timerId)
this._timerId = setTimeout(() => {
this.fetchData()
}, 200)
}
},
watch: {
search (val) {
if(val == null || val == "") return
if(this.model){
if(val == this.model.CodeAndName) return
}
this.fetchDebounced()
},
}
}
As you can see in the item-text property of the autocomplete component, I'm passing "CodeAndName" which is an attribute I made so that it would search for both Code and Name of the item. This means it will show both in the search bar after a selection is made. However I want it to show only name, while searching for both code and name. I have tried passing an array into item-text but that didn't work either. I also don't know what item-value is for, the docs don't specify.
Also I don't know if this matters, but when the API is called, it will return the first 10 results where
if searchterm in item.Code or searchterm in item.Name
As mentioned in docs You can define your custom filter method like
customFilter (item, queryText, itemText) {
const textOne = item.CodeAndName.toLowerCase()
const searchText = queryText.toLowerCase()
return textOne.indexOf(searchText) > -1
}
and pass it in
<v-autocomplete
spellcheck="false"
:filter="customFilter"
...
</v-autocomplete>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With