Yashar Vasegh
Yashar Vasegh

Reputation: 1

quasar q-select infinite scroll

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

Answers (3)

Bakhtiyor Sulaymonov
Bakhtiyor Sulaymonov

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

Sid
Sid

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

Yashar Vasegh
Yashar Vasegh

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

Related Questions