Trigger shimmer loading indicator without DataManager

I tried referencing the example in the docs:

https://ej2.syncfusion.com/vue/documentation/grid/loading-animation

But this approach relies on the DataManager.


I want to asyncronously update the grid dataSource, and render the shimmer while awaiting that update.

I want to initialize the dataSource as an empty array and render the grid with the loading shimmer, make an api call, and then update the grid/ dataSource with the data returned by my api.


I've tried multiple methods, including the Custom Data binding approach, but none of them cause the grid to enter a loading state/ render the shimmer.


I've tried several approaches to forcing a loading state:


const dataSource = []


const dataSource = {result:[], count:0} //as referenced in Custom Data binding


const dataSource = new Promise(()=>{})


const dataSource = new Promise((resolve, reject) =>{

resolve([])

}


onMounted(grid.value.showMaskRow()) //as referenced in another support thread


None of these cause the grid to render the loading shimmer.

Either the records render, or the grid simply displays "No records to display" message.

I tested with the DataManager, and the spinner does indeed render.

I'm just no understanding what actually triggers the spinner/shimmer to render.

What is DataManager returning, and how can I replicate in my own code?


5 Replies

HS Hemanthkumar S Syncfusion Team June 23, 2023 12:58 PM UTC

Hi Ryan Sereno,


Greetings from Syncfusion support.


Query: Trigger shimmer loading indicator without DataManager


Based on the information you provided, we understand that you have a requirement to display or hide a Spinner or Shimmer based on certain conditions. In response to your request, we have prepared a sample-level solution where we suggest utilizing the showSpinner or showMaskRow method of the Grid component to display the spinner or shimmer in the Grid. Additionally, we recommend using the hideSpinner or removeMaskRow methods to hide the spinner or shimmer in the Grid, based on your specified conditions.


For more information, please refer to the below code example, video, and sample.

[App.vue]

 

  <button @click="showSpinner">Show Spinner</button>

  <button @click="hideSpinner">Hide Spinner</button>

  <button @click="showShimmer">Show Shimmer</button>

  <button @click="removeShimmer">Remove Shimmer</button>

  

 

methods: {

    showSpinner() {

      this.$refs.grid.showSpinner();

    },

    hideSpinner() {

      this.$refs.grid.hideSpinner();

    },

    showShimmer() {

      this.$refs.grid.showMaskRow();

    },

    removeShimmer() {

      this.$refs.grid.removeMaskRow();

    },

  },

 


Sample Link: https://stackblitz.com/edit/vue-ozozfc?file=src%2FApp.vue


Please feel free to contact us if you require any further assistance. We are always available and eager to help you in any way we can.


Regards,

Hemanth Kumar S


Attachment: video_d1eea5a7.zip


RS Ryan Sereno replied to Hemanthkumar S June 23, 2023 08:36 PM UTC

Thank you
I am able to get the spinner to appear with a button, but not with the onMounted hook (I am using Vue 3 and the composition api)

This does not work:

onMounted(async()=>{
grid.value.showSpinner()
await fetchData()
grid.value.hideSpinner()
});
How would I show spinner when awaiting an asynchronous operation?

Edit:
This appears to work.

onMounted(async () => {

  setTimeout(() => {

    grid.value.showSpinner(); // Access the grid methods after a delay

  }, 1000);

});


The showSpinner/Shimmer method is not available on mount.
Is there a cleaner solution to this than a setTimeout?



HS Hemanthkumar S Syncfusion Team June 26, 2023 11:29 AM UTC

Hi Ryan Sereno,


Query: Is there a cleaner solution to this than a setTimeout?


Based on the information you provided, we understand that you want to display and hide a spinner for the Grid during a custom data-binding approach. Typically, in a custom data-binding scenario, you need to manually handle the display and hiding of the spinner.


Considering your update, we have prepared a solution at the sample level. We suggest creating a custom spinner using the Syncfusion EJ2 Spinner component inside the load event of the Grid. This allows you to show the spinner while the data is being loaded. Once the API data is assigned to the Grid, you can hide the spinner inside the dataBound event of the Grid.


This approach provides you with control over when to display and hide the spinner, ensuring a smooth user experience during the custom data-binding process.


For more information, please refer to the below code example, API documentation, video, and sample.

[App.vue]

 

  <ejs-grid

    ref="grid"

    id="grid1"

    :dataSource="data"

    :allowFiltering="true"

    :filterSettings="filterOptions"

    :load="load"

    :dataBound="dataBound"

  >

 

  setup() {

    onMounted(async () => {

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      await new Promise((resolve=> {

        setTimeout(resolve3000);

      });

      gridInst.dataSource = [

        {

          OrderID: 10248,

          OrderDate: new Date('2023-05-04T00:00:00Z'),

          ShipCountry: 'France',

        },

        {

          OrderID: 10249,

          OrderDate: new Date('2023-06-04T00:00:00Z'),

          ShipCountry: 'Germany',

        },

        {

          OrderID: 10250,

          OrderDate: new Date('2023-07-04T00:00:00Z'),

          ShipCountry: 'USA',

        },

      ];

    });

  },

 

  data() {

    return {

      data: [],

      country: [],

      filterOptions: { type: 'Menu' },

      dateFormat: { type: 'datetime'format: 'y/MM/dd - HH:mm:ss' },

    };

  },

  methods: {

    load(args) {

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      const defaultSpinner = gridInst.element.querySelector('.e-spinner-pane');

      defaultSpinner.style.display = 'none';

      gridInst.element.insertAdjacentHTML(

        'beforeend',

        `<div class="custom-spinner"></div>`

      );

      this.createSpinner();

    },

    createSpinner() {

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      const customSpinnerHTMLElement =

        gridInst.element.querySelector('.custom-spinner');

      createSpinner({ target: customSpinnerwidth: '30px' });

      this.showSpinner();

    },

    showSpinner() {

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      const customSpinnerHTMLElement =

        gridInst.element.querySelector('.custom-spinner');

      showSpinner(customSpinner);

    },

    hideSpinner() {

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      const customSpinnerHTMLElement =

        gridInst.element.querySelector('.custom-spinner');

      hideSpinner(customSpinner);

    },

    dataBound(args) {

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      if (gridInst.currentViewData.length) {

        this.hideSpinner();

      }

    },

  },

 


load API: https://ej2.syncfusion.com/documentation/api/grid/#load

dataBound API: https://ej2.syncfusion.com/documentation/api/grid/#databound


Sample Link: https://stackblitz.com/edit/vue-tb4hrw?file=src%2FApp.vue


Please feel free to contact us if you require any further assistance. We are always available and eager to help you in any way we can.


Regards,

Hemanth Kumar S


Attachment: video_6eb7acc2.zip


RS Ryan Sereno replied to Hemanthkumar S June 26, 2023 02:24 PM UTC

Thank you
So there is no way to achieve this with the shimmer?
Since this approach requires adding an additional spinner element on top of the grid?



HS Hemanthkumar S Syncfusion Team June 30, 2023 02:25 PM UTC

Hi Ryan Sereno,


Query: way to achieve this with the shimmer?


Based on the information you provided, it seems that you want to control the display and hiding of the shimmer for the Grid during a custom data-binding approach. In such scenarios, you need to handle the shimmer display and hiding manually. To achieve this, you can use the showMaskRow and removeMaskRow methods of the Grid. We recommend setting the loadingIndicator.indicatorType as Shimmer to configure the Grid for displaying the shimmer instead of the spinner.


Considering your request, we have prepared a sample-level solution. We suggest calling the showMaskRow method inside the dataBound event of the Grid during the initial data processing. It's important to note that by default, whenever the dataBound event of the Grid is triggered, the shimmer will be removed automatically. So when you bind data to the Grid, the dataBound event will be triggered, leading to the automatic removal of the shimmer. Alternatively, you can manually remove the shimmer by calling the removeMaskRow method whenever needed.


For more information, please refer to the below code example, video, and sample.

[App.vue]

 

  <ejs-grid

    ref="grid"

    id="grid1"

    :dataSource="data"

    :allowFiltering="true"

    :filterSettings="filterOptions"

    :dataBound="dataBound"

    :loadingIndicator="loadingIndicator"

  >

 

  setup() {

    const instance = getCurrentInstance();

    onMounted(async () => {

      await new Promise((resolve=> {

        setTimeout(resolve5000);

      });

      instance.proxy.dataReceived = true;

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      gridInst.dataSource = [

        {

          OrderID: 10248,

          OrderDate: new Date('2023-05-04T00:00:00Z'),

          ShipCountry: 'France',

        },

        {

          OrderID: 10249,

          OrderDate: new Date('2023-06-04T00:00:00Z'),

          ShipCountry: 'Germany',

        },

        {

          OrderID: 10250,

          OrderDate: new Date('2023-07-04T00:00:00Z'),

          ShipCountry: 'USA',

        },

      ];

    });

  },

  data() {

    return {

      data: [],

      country: [],

      dataReceived: false,

      loadingIndicator: { indicatorType: 'Shimmer' },

      filterOptions: { type: 'Menu' },

      dateFormat: { type: 'datetime'format: 'y/MM/dd - HH:mm:ss' },

    };

  },

  methods: {

    dataBound(args) {

      const gridInst = document.getElementById('grid1').ej2_instances[0];

      if (!this.dataReceived) {

        gridInst.showMaskRow();

      }

    },

  },

 


Sample Link: https://stackblitz.com/edit/vue-p6apmw?file=src%2FApp.vue


Please feel free to contact us if you require any further assistance. We are always available and eager to help you in any way we can.


Regards,

Hemanth Kumar S


Attachment: video_64896574.zip

Loader.
Up arrow icon