Implement a loading bar on the entire page in Vue.js while a request is being made

There is an "edit" button on my page which allows me to edit certain elements and either save or close without saving.

I would like to implement a loading bar that displays when the user clicks the "save" button, indicating that the data is being processed before showing the results.

Current functionality:

After clicking the "edit" button, editable data appears with options to "save" or "close" (which dismisses changes). Clicking "save" reloads the page with updated data and displays an "updated" message, or shows an error message if the update fails.

Desired functionality:

Upon clicking the "save" button after making edits, I want the page to show a loading bar for a few seconds (e.g. 5 seconds). If the request completes within that time, the loading bar disappears; otherwise, it continues until completion. The page then displays the updated data and the "updated" notification.

Below are snippets related to this feature:

Button setup:

Insert code snippet here

Edit function:

Insert code snippet here

For the progress bar, I am utilizing Vuetify's circular progress component.

   <v-progress-circular
    v-show="loading"
    indeterminate
    color="primary">
   </v-progress-circular>

Struggling to determine where in the code to place this element for it to display correctly throughout the entire page. Placing it before or inside the buttons has not yielded the desired result.

Answer №1

If you're looking for a solution, one approach could be to implement an overlay that is positioned at the bottom of your root element.

Here's a basic example to give you an idea:

         <v-col cols="3">
          <v-btn
            v-if="editGroup"
            light
            class="mx-2"
            @click="editGroup = false"
          >
            <v-icon left>mdi-close</v-icon>
            Close
          </v-btn>
          <v-btn
            v-if="editGroup" 
            light 
            class="mx-2" 
            @click="clickSave"
            >
            <v-icon left>mdi-content-save</v-icon>
            Save
          </v-btn>
          <v-btn
            v-if="
              canShowButton(['administrator', 'configurator']) &&
              !editGroup
            "
            light
            class="mx-2"
            @click="editGroup = true"
          >
            <v-icon left>mdi-pencil</v-icon>
            Edit
          </v-btn>
          <--The overlay will only display when loading state is true-->
          <v-overlay v-model="loading">
            <v-progress-circular
            indeterminate
            color="primary">
            </v-progress-circular> 
          </v-overlay>
        </v-col>

The overlay will be visible across the entire screen as long as the loading state remains true.

Check out the Vuetify documentation on overlays for more information.

Edit:

In addition, make sure to initialize the loading state in the data section of your page upon initial load.

<script>
  export default {
    data: () => ({
      loading: false,
    }),
    },
  }
</script>

Answer №2

State management with tools like pinia is essential for efficient data handling. By setting up a pinia store in the following manner:

import { defineStore } from "pinia"

export enum PageState {
  LOADING,
  LOADED,
  ERROR
}

export const usePageStore = defineStore({
  state: () => ({
    pageState: PageState.LOADED
  }),
  getters: {},
  actions: {
    saveData(endpointPrefix, groupId, newData) {
      try {
        // Perform URL building and data processing here
      } catch (e) {
        throw new Error(e)
      }
    },
  },
})

Instead of handling all data operations within your Vue script, you can simply do this:

pageStore = usePageStore()

async clickSave() {
  try {
    pageStore.pageState = PageState.LOADING
    const response = await pageStore.getData(this.endpointPrefix, this.groupId, dat)
    this.$nuxt.$emit('show-notification', {
          text: 'updated',
          color: 'green',
        })
    this.loadData(this.groupid)
    pageStore.pageState = PageState.LOADED
  } catch (e) {
    pageStore.pageState = PageState.ERROR
     this.$nuxt.$emit('show-notification', {
        text:
          'could not be updated !' +
          error.response.data,
        color: 'red',
      })
  }  
}

Your main page view can then access the same store, monitor that variable, and adjust accordingly to display the necessary information.

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

AngularJS OAuth authentication Pop-up: Waiting for JSON response

I am looking to initiate an oauth request in a new window for my project. Here is how I can open the new window: var authWindow = $window.open("/auth/google/signin", ""); After the callback, my server will respond with JSON data: app.get('/auth/ ...

The enigmatic loop traversal

Can you figure out why the name property of the merged object is properly set in the code below, even though the for-loop starts with i = 1? function merge(root){ for ( var i = 1; i < arguments.length; i++ ){ for ( var key in arguments[i] ){ ...

react-i18next - The function call does not match any overload when the specified type is `string`

I am currently utilizing react-i18next in conjunction with React and TypeScript. Interestingly, when I attempt to load a property using a string literal and type inference, everything works seamlessly. However, once I specify the type as string, an error i ...

Utilizing Javascript to Connect with Java Web API

I'm seeking assistance with transferring a file from a browser to another device connected to a server-operated machine. I am relatively new to web application and back-end programming. The current code allows for moving a file from the server to the ...

Utilize the data stored in chrome.storage within the Vue.js data

I'm currently developing a Chrome app where I am utilizing Vue.js for the options page. My goal is to retrieve settings from Chrome storage and inject them into the Vue data. However, I am encountering an issue where I am unable to access Vue compone ...

Four unique chip/tag colors, personalized to suit your style

Currently, I have integrated two arrays into my autocomplete menu where the chip/tag color is either primary or secondary based on the array the selected component belongs to. I aim to include all four arrays in the menu (top10Songs, top10Artists, top10Fi ...

How can I add content to the body of a modal in Bootstrap 3?

My application has a button that, when clicked, is supposed to trigger a modal popup containing some data. I want the data in the modal to come from another application via a PHP file accessed through a URL. How can this be achieved? <?php echo '& ...

Using jQuery and JSON data to dynamically populate a second dropdown menu with filtered options

I am working on a form with two drop-down menus and a text box. The first drop-down contains static values, while the second drop-down is populated dynamically from a JSON array. My goal is to filter the options in the second drop-down based on the selecti ...

Attempting to modify the state within a nested object located in an array by using json data

My objective is to retrieve data from the Google Books API, which returns JSON data in a similar format to what my state displays. I aim to update the title with the title string provided by the JSON data. Currently, I am encountering a "failed to compile" ...

Bring in numerous documents utilizing a glob pattern

Currently, I am in the process of developing a modular React application. However, I have encountered an issue where I am unable to dynamically import the routes for my app. Consider the following file structure: app ├── app.js └── modules ...

Laravel: The current configuration does not support the experimental syntax 'classProperties' at this time

When compiling my javascript files using npm run dev, I encountered a warning in my resource/app.js file where I require my custom validation script. The warning stated the following: Module build failed (from ./node_modules/babel-loader/lib/index.js): Syn ...

Prevent Repeated Data Input in an Array using JavaScript

I am facing an issue where I need to ensure that the values being inserted are not repeated when performing a push operation. Below is the snippet of code in question: addAddress: function() { this.insertAddresses.Address = this.address_addres ...

Single-select components in React Native

I am currently working on implementing a simple single selectable item feature, illustrated in the image provided below. https://i.stack.imgur.com/U2rJd.png At this moment, I have set up an array containing my data items and utilized the .map function to ...

What is the method of adding a child to the outerHTML of the parent element instead of within it?

Is there a way to use the outerHTML method on a parent element to append a child element so that the icons appear outside of the targeted element rather than inside it? The current code snippet shows the icons inside the box, but I want them to be placed o ...

Utilizing turbolinks enables the page to be reloaded upon form submission

Currently, I have implemented turbolinks in my Rails application. However, every time I submit a form, the page reloads and the form is submitted. Is there a way to prevent the page from reloading and also submit the form seamlessly? ...

Sharing data between two Angular 2 component TypeScript files

I'm facing a scenario where I have two components that are not directly related as parent and child, but I need to transfer a value from component A to component B. For example: In src/abc/cde/uij/componentA.ts, there is a variable CustomerId = "sss ...

Ways to retrieve arrow information in JavaScript?

I'm currently retrieving tabular data in Arrow format from an API where the response content-type is application/vnd.apache.arrow.stream. Within my React code, I am attempting to parse this response. However, I'm uncertain if this approach is the ...

Stop the slider when a video pops up

Years ago, I had a slider created for me that supports both images and video with a timer. However, the issue I'm facing is that when the timer runs every 10 seconds, the video gets cut off if it's not finished playing. Below is the json file st ...

The Vue and Typescript webpage is not appearing in the GAS sidemenu template

I am tasked with developing an application for Google Sides using Vue + Typescript to enhance its functionality with an extra menu feature. You can find a sample without Typescript here. The result is visible in this screenshot: https://gyazo.com/ed417ddd1 ...

What is the proper method for initiating an ajax request from an EmberJs component?

Curious to learn the correct method of performing an ajax call from an Ember component. Let's say, for instance: I am looking to develop a reusable component that allows for employee search based on their Id. Once the server responds, I aim to update ...