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?
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
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?
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(resolve, 3000); }); 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 customSpinner: HTMLElement = gridInst.element.querySelector('.custom-spinner'); createSpinner({ target: customSpinner, width: '30px' }); this.showSpinner(); }, showSpinner() { const gridInst = document.getElementById('grid1').ej2_instances[0]; const customSpinner: HTMLElement = gridInst.element.querySelector('.custom-spinner'); showSpinner(customSpinner); }, hideSpinner() { const gridInst = document.getElementById('grid1').ej2_instances[0]; const customSpinner: HTMLElement = 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
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?
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(resolve, 5000); }); 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