Reputation: 1
How to apply infinite scroll on q-select? I see there is "virtual-scroll" event which return this json
,
{index: 11, from: 0, to: 11, direction: 'increase', ref: VueComponent}
But the problem is when you are using mouse and scrolling, it is not updating the index parameter in returned data, and the index is always the position of the last greyed item, but with keyboard it is working as you are always moving the greyed item in selected list.
How to know scroll is near end to trigger fetch data? Should I take another approach.
Upvotes: 0
Views: 945
Reputation: 382
I think what you want is implemented in Dynamic loading options as described in docs.
You can add @virtual-scroll event and you can trigger fetchData in it's handler.
Example from docs:
// Template
<q-select
filled
v-model="model"
multiple
:options="options"
:loading="loading"
@virtual-scroll="onScroll"
/>
// Script
setup () {
const loading = ref(false)
const nextPage = ref(2)
const options = computed(() => allOptions.slice(0, pageSize *
(nextPage.value - 1)))
return {
model: ref(null),
loading,
nextPage,
options,
onScroll ({ to, ref }) {
const lastIndex = options.value.length - 1
if (loading.value !== true && nextPage.value < lastPage && to ===
lastIndex) {
loading.value = true
setTimeout(() => {
nextPage.value++
nextTick(() => {
ref.refresh()
loading.value = false
})
}, 500)
}
}
}
Upvotes: 0
Reputation: 1
Thanks Yashar for your solution.
Hope this helps further:
Template:
<template>
<q-select
dense
outlined
square
use-input
hide-selected
fill-input
v-model="goodsData1.code"
:label="Goods Code"
:options="options"
@focus="getFocus(1)"
@input-value="setOptions"
@filter="filterFn"
>
<template v-slot:no-option>
<q-item><q-item-section class="text-grey">No results</q-item-section></q-item>
</template>
<template v-slot:option="scope">
<q-infinite-scroll @load="loadMoreOptions" :offset="25">
<q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
<q-item-section>{{ scope.opt.label }}</q-item-section>
</q-item>
</q-infinite-scroll>
</template>
</q-select>
</template>
Data:
data() {
return {
options: [],
goodsData1: { code: '', qty: '' },
currentPage: 1,
totalResults: 0,
isLoading: false,
inputValue: ''
// other necessary data
}
}
Methods:
methods: {
getFocus (number) {
this.listNumber = number
},
setOptions (val) {
if (!val) {
this[`goodsData${this.listNumber}`].code = ''
}
this.inputValue = val
this.currentPage = 1
this.options = []
this.fetchOptions(val)
},
fetchOptions (val) {
const needle = val.toLowerCase()
this.isLoading = true
let url = ``API call url``
getauth(url).then(res => {
const goodscodelist = []
for (let i = 0; i < res.results.length; i++) {
goodscodelist.push({
label: res.results[i].goods_code,
value: res.results[i].goods_code
})
if (this.listNumber) {
if (res.results[i].goods_code === val) {
this[`goodsData${this.listNumber}`].code = val
}
}
}
this.options = [...this.options, ...goodscodelist]
this.totalResults = res.count
this.isLoading = false
})
},
loadMoreOptions (index, done) {
if (this.options.length >= this.totalResults || this.isLoading) {
done()
return
}
this.currentPage++
this.fetchOptions(this.inputValue)
done()
},
filterFn (val, update, abort) {
if (val.length < 1) {
abort()
return
}
update(() => {
this.setOptions(val)
})
}
// other methods...
}
Upvotes: 0
Reputation: 1
This is the solution,
<q-select>
<template v-slot:option="scope">
<q-infinite-scroll @load="onLoad" :offset="25">
<q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
</q-item>
</q-infinite-scroll>
</template>
</q-select>
Upvotes: 0