Creating endless scroll feature in Vuetify's Autocomplete component - A comprehensive guide

Having trouble with my Vuetify Autocomplete component and REST API backend. The '/vendors' method requires parameters like limit, page, and name to return JSON with id and name.

I managed to implement lazy loading on user input, but now I want it to load vendors on user scroll event as well.

Imagine there are initially 100 vendors in the list. When a user scrolls to the end, an event should trigger to load the next 100 vendors. This process repeats as the user continues scrolling.

Do you think it's achievable with the Vuetify Autocomplete component, or should I consider using a different library?

The example code for the current component is provided below:

<template>
  <v-autocomplete
          :items="vendors"
          v-model="selectedVendorId"
          item-text="name"
          item-value="id"
          label="Select a vendor"
          @input.native="getVendorsFromApi"
  ></v-autocomplete>
</template>

<script>
  export default {
    data () {
      return {
        page: 0,
        limit: 100,
        selectedVendorId: null,
        vendors: [],
        loading: true
      }
    },
    created: function (){
      this.getVendorsFromApi();
    },
    methods: {
      getVendorsFromApi (event) {
        return new Promise(() => {
          this.$axios.get(this.$backendLink 
                  + '/vendors?limit=' + this.limit 
                  + '&page=' + this.page 
                  + '&name=' + (event ? event.target.value : ''))
            .then(response => {
              this.vendors = response.data;
            })
        })
      }
    }
  }
</script>

Answer №1

Implementing auto-loading functionality with the Vuetify AutoComplete component was an interesting challenge that I managed to overcome. The solution involved utilizing the v-slot append item along with the v-intersect directive to determine if the appended item is visible on the screen. When it becomes visible, an API call is made to fetch more items and add them to the existing list.

  <v-autocomplete
          :items="vendors"
          v-model="selectedVendorId"
          item-text="name"
          item-value="id"
          label="Select a vendor"
          @input.native="getVendorsFromApi"
  >
  <template v-slot:append-item>
    <div v-intersect="endIntersect" />
  </template>
</v-autocomplete>


...

export default {
  methods: {
    endIntersect(entries, observer, isIntersecting) {
      if (isIntersecting) {
        let moreVendors = loadMoreFromApi()
        this.vendors = [ ...this.vendors, ...moreVendors]
      }
    }
  }
}

In my scenario, I integrated API Platform as the backend and employed GraphQL pagination with a cursor for navigation.

Answer №2

Latest Update June 12, 2021:

For users of Vuetify 2.X, I recommend utilizing Brettins' solution which makes use of the append-item slot and v-intersect directive.


Previous Solution:

It appears that achieving this feature is not natively supported in the default v-autocomplete component, especially in versions prior to vuetify 1.5.16. An alternative component that offers similar functionality is VueInfiniteAutocomplete.

However, it's important to note that using this alternative may lead to issues with styles, validation, and other aspects.

An example implementation utilizing VueInfiniteAutocomplete is provided below.

<template>
    <div>
    <vue-infinite-autocomplete
      :data-source="getAsyncOptions"
      :fetch-size="limit"
      v-on:select="handleOnSelect"
      :value="autocompleteViewValue"
    >
    </vue-infinite-autocomplete>
  </div>
</template>
<script>
  export default {
    data () {
      return {
          selectedVendorId : null,
          limit: 100,
          autocompleteViewValue: null
      }
    },
    methods: {
        getAsyncOptions(text, page, fetchSize) {
            return new Promise((resolve, reject) => {
                resolve(
                    this.$axios.get(this.$backendLink
                        + '/vendors?limit=' + fetchSize
                        + '&page=' + page
                        + '&name=' + text)
                        .then(response => {
                            //Response MUST contain 'id' and 'text' fields, and nothing else.
                            //If there are other fields, you should remove them here
                            //and create 'id' and 'text' fields in response JSON manually
                            return response.data;
                        })
                )
            });
        },

        handleOnSelect(selectedItem) {
            this.autocompleteViewValue = selectedItem.text;
            this.selectedVendorId = selectedItem.id;
        }
    }
  }
</script>

Note: If your preference is to stick with the v-autocomplete component and implement server-side pagination, one approach could be adding a "Load more..." button through the append-item slot, as discussed in this thread.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What causes the failure of $event binding when using RowGroup tables with PrimeNG?

I have successfully implemented RowGroup to store 3 different tables, which is working great. However, I am facing an issue with the onRowSelect function not functioning properly. When I click on any row of the RowGroup tables, nothing happens. On another ...

Why isn't the jQuery colorbox popup appearing when triggered by the $.ajax() function?

I am currently facing an issue where I am trying to display a hidden colorbox popup using the $.ajax() method's success function, but it is not showing up. Interestingly, this had worked fine in a previous implementation where I used the data attribut ...

Adding custom styles to an unidentified child element in React using Material-UI

When the function below is executed in a loop, I need to include styles for the icon which will be passed as an argument to the function. The icon element will be an unspecified React Material-UI Icon component. const renderStyledCard = (lightMode, headi ...

Surprising behavior encountered while utilizing fsPromises.open with Node.js

As I work on a larger app, I encounter an issue with a file writing operation. I am utilizing fsPromises to generate an autosave file, but the path variable seems to lose its value between a console log for debugging and the actual call to open the file. I ...

Is it necessary to use both Vue Router and Express when incorporating Firebase into your project?

I am embarking on creating a simple application that will encompass various views, user authentication, data collection, database storage, and backend functionality to process and display the stored information. My chosen technology stack consists of Vue. ...

Having trouble testing a basic Vue example component in Laravel 5.4

I recently installed Laravel 5.4 and after running npm install, I tested a vue component example but nothing happened as expected. After running npm run dev in my project directory, the compilation was successful. However, when I ran php artisan serve, al ...

Leveraging arrays generated from two separate MySQL queries for dual selection functionality with JavaScript

I have successfully populated the first HTML select with results from the first query. Now, I would like to store the results from the second query in either a Json file or XML and then use plain javascript (not jQuery) to populate the second HTML select ...

byte sequence displays as binary data (angular + express)

I've been working on pulling files from a back-end Node.js / Express server and displaying them in an Angular front-end. Despite trying different methods, I keep facing the same issue - the data displayed at the front-end appears as a bytestring. Even ...

using async/await to retrieve data from a Google spreadsheet in Node.js

How can I use a for-loop to iterate through sheets in a Google spreadsheet and access specific cells within each sheet? I have a Google spreadsheet with Sheet1, Sheet2,... , Sheet5 where the cell values are Value1,..., Value5. The expected result should be ...

Creating a grid in JavaScript using a formula

I'm looking to create a grid of objects using JavaScript. Unfortunately, I can't remember the formula and I haven't been able to find it online: var width = 113; var height = 113; var col = 10; ...

A guide on updating a boolean field in the database using ajax

Here is a piece of my html code: <form action="" method="post"> {% csrf_token %} {% if donate.is_taken == False %} <br> <button type="submit" class="btn" name="taken_or_not" ...

What is the best way to add query parameters to router.push without cluttering the URL?

In my current project, I am using NextJS 13 with TypeScript but not utilizing the app router. I am facing an issue while trying to pass data over router.push to a dynamically routed page in Next.js without compromising the clarity of the URL. router.push({ ...

What causes the function to return null when using router.get('/:x',..), whereas router.get('/foo/:x',...) works perfectly fine?

After weeks of struggling to identify the root cause of my issue, I finally pinpointed it. Now, I'm curious to understand the reason behind this behavior. I constructed an api for my mongodb server following the techniques I learned in school, utiliz ...

There seems to be an issue with the reactivity in the Vue Composition API

Currently utilizing Vue2, Vuetify, and the Vue Composition API (@vue/composition-api). Encountering an issue with the reactivity of the composition API. Let's delve into some code snippets: ---- companies.vue ---- <template> ... <v-data ...

The issue arises when trying to use destructured imports with Mongoose

I've been developing a straightforward Express app with ES6. In the process of creating a schema and model for Mongoose, I encountered an issue with the following syntax: import mongoose, { Schema } from 'mongoose'; const PostSchema = new ...

Importing XML data into a JavaScript variable using jQuery without displaying an alert message

Despite previously asking questions about loading XML into a JS variable, I haven't found a satisfactory solution. In my script, I declare a variable before making an ajax request and then assign the result to that variable. However, this only seems t ...

Refresh web content dynamically without having to reload the entire page using JavaScript

Currently, I am struggling to find a solution on how to dynamically update a section of a webpage using JavaScript when a user modifies an input field in another part of the same page. Unfortunately, my use of document.write is inhibiting me from making th ...

Error: Encountered an unexpected asterisk symbol while trying to import a Sequelize model from the

Currently, I am developing an application that requires me to connect and run queries on an SQL server using Sequelize. I have set up migrations, seeders, and models by utilizing sequelize init. However, when attempting to generate model objects with const ...

Sending a JSONP request to a PHP script

For my application submission, I am trying to send a JSON object to a PHP script that will return a JSON response. The challenge here is that the domain does not comply with the same-origin policy, meaning the JSON is being sent from a different domain. Up ...

Showing JSON response on an HTML page using AngularJS

I have limited experience with JavaScript and/or Angular, but I am required to utilize it for a research project. My task involves showcasing the JSON data returned by another component on a webpage. Here is how the process unfolds: When a user clicks on ...