Vue-tables-2: custom loading indicator

Created on 24 Nov 2017  路  4Comments  路  Source: matfish2/vue-tables-2

First of all, great project! Adding to #301. Would you be able to provide a quick code example of how to how to replace the default "Loading..." indicator with a custom option?

brainstorming help wanted

Most helpful comment

I managed to achieve this using the afterBody slot. Does require some additional CSS but seems to work well.

Example:

Imgur

Template

<v-server-table  :url="tableGetUrl" :columns="columns" :options="options">
    <template v-if="isLoading" slot="afterBody">
        <div class="overlay-loader"></div>
        <clip-loader size="50px" class="clip-loader"></clip-loader>
    </template>
</v-server-table>

Script

import ClipLoader from 'vue-spinner/src/ClipLoader.vue'
export default {
    components: {
        "clip-loader": ClipLoader
    },
    data() {
        return {
            isLoading: false,
        },
    },
    mounted() {
        this.prepareComponent();
        Event.$on('vue-tables.loading', () => {
            this.isLoading = true;
        });
        Event.$on('vue-tables.loaded', () => {
            this.isLoading = false;
        });
    },
    ...
}

CSS

table {
  width: 100%;
  position: relative;
}

.overlay-loader {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: white;
    opacity: 0.8;
    filter: blur(5px);
}

.clip-loader {
    position: absolute;
    left: 50%;
    right: 50%;
    bottom: 60%;
    top: 40%;
}

All 4 comments

The default loading text is only shown once, when the table is loaded for the first time. It can be changed using the texts.loading option. As for subsequent requests I thought replacing the current content with the loading row would not be the best UX. Instead, you can use the complementary loading and loaded events to display a custom loading indicator next to the table, above it, or as an overlay on top of it.

E.g:

<template>
<div class="table">
    <span> class="loading-indicator" v-if="loading"></span>
    <v-server-table></v-server-table>
</div>
</template>
export default {
data() {
    return {
       loading: false
    }
},
mounted() {
    Event.$on('vue-tables.loading', ()=>{
        this.loading = true;
    });

    Event.$on('vue-tables.loaded',()=>{
        this.loading = false;
    });
   }
}

Thanks for the response! That's definitely helpful. I tried adding a loading spinner as a overlay over the table body, but I couldn't quite get it to work (I'm pretty terrible with css). I thought maybe adding the spinner as a beforeBody or prependBody slot might help but that always seemed to place the spinner under the first column for some reason. Could you provide some example css with the code above that would overlay the span element over the <tbody>?

My current solution just mimics the 'no-results` row to add the spinner:

    <v-server-table ref="userTable" url="" :columns="columns" :options="options">
      <template slot="beforeBody">
        <tr v-if="loading" class="VueTables__no-results">
          <td class="text-center" colspan="6"><pulse-loader></pulse-loader></td>
        </tr>
      </template>
    </v-server-table>

I suppose I can add a beforeTable slot that will allow you to add not-tabular elements after the wrapper and before the table element, but that will cover the whole table, and you want only the tbody.
Otherwise, I don't know how to achieve this with CSS.

I managed to achieve this using the afterBody slot. Does require some additional CSS but seems to work well.

Example:

Imgur

Template

<v-server-table  :url="tableGetUrl" :columns="columns" :options="options">
    <template v-if="isLoading" slot="afterBody">
        <div class="overlay-loader"></div>
        <clip-loader size="50px" class="clip-loader"></clip-loader>
    </template>
</v-server-table>

Script

import ClipLoader from 'vue-spinner/src/ClipLoader.vue'
export default {
    components: {
        "clip-loader": ClipLoader
    },
    data() {
        return {
            isLoading: false,
        },
    },
    mounted() {
        this.prepareComponent();
        Event.$on('vue-tables.loading', () => {
            this.isLoading = true;
        });
        Event.$on('vue-tables.loaded', () => {
            this.isLoading = false;
        });
    },
    ...
}

CSS

table {
  width: 100%;
  position: relative;
}

.overlay-loader {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: white;
    opacity: 0.8;
    filter: blur(5px);
}

.clip-loader {
    position: absolute;
    left: 50%;
    right: 50%;
    bottom: 60%;
    top: 40%;
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

manrix picture manrix  路  3Comments

nuneramu picture nuneramu  路  7Comments

ydogus picture ydogus  路  3Comments

zhlc2008 picture zhlc2008  路  3Comments

singiankay picture singiankay  路  4Comments