Search code examples
asp.net-core.net-coreasp.net-core-mvc

Display progress image / spinner in ASP.NET Core MVC application


I am working on converting a legacy application to ASP.NET Core MVC. I have a long running process which returns data only after 15 seconds. I have done all methods to optimise the backend procedure including adding custom paging but could not reduce the execution time any further.

On the click of the process button, a procedure is executed to insert data and then return data based on the filter parameters. I want to display a progress image in the view so that the user gets to know about the data processing operation. The process button is present in a modal popup in the view.

This is my view :

<form class="mt-4" id="myform" name="myform" asp-controller="Process" asp-action="YearEndProcess" method="post">
 <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
    <!-- Modal title -->
    <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">Year End Processing</h3>
    <br />
    <div class="grid grid-cols-2 gap-4">
        <!-- Select Year -->
        <div>
            <label class="block text-sm font-medium text-gray-700">
                <i class="fas fa-calendar-alt text-blue-600 mr-1"></i> PROC YEAR
            </label>            
            <select id="procYrDropdown" asp-for="SelectedProcYear" required class="form-control w-full mt-1">
                <option value="">Select Proc Yr</option>
            </select>
            <span asp-validation-for="SelectedProcYear" class="text-danger field-validation-valid"></span>
        </div>
        <!-- Select Month -->
        <div>
            <label class="block text-sm font-medium text-gray-700">
                <i class="fas fa-calendar-check text-green-600 mr-1"></i> PROC MONTH
            </label>
            <select class="form-control w-full mt-1" id="procMonthDropdown" required asp-for="SelectedProcMonth">
                <option value="">Select Proc Month</option>                   
            </select>
            <span asp-validation-for="SelectedProcMonth" class="text-danger field-validation-valid"></span>
        </div>           
    </div>
</div>
<!-- Modal footer -->
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
    <button type="submit" value="process"
        class="w-full inline-flex justify-center rounded-md border border-transparent px-4 py-2  text-base font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"
        style="background-color: #5000bb;">
        @*onclick="showProcessingModal()"*@           
    </button>
    <button type="button"
        class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 px-4 py-2 bg-white text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:w-auto sm:text-sm"
        onclick="hideModal()">
        Cancel
    </button>
</div>

This is my controller :

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> YearEndProcess(ProcessingViewModel processData)
    {
    if (ModelState.IsValid)
    {
    YearEndProcessBAL yearEndProcessBAL = new(_configuration);
    result re = new();
    try
    {
    re = await yearEndProcessBAL.Process(processData);    
    processData.processedData = await yearEndProcessBAL.getProcessedData(processData, 1);
    }
    catch (Exception ex)
    {
    _logger.LogError("Error occured during processing.", processData);
    }
    }
    return View("YearEndProcess", processData);
    }

I am new to .NET Core. Any help is greatly appreciated. Thank you.


Solution

  • I have created a simple solution to display a spinner image using a partial view and a simple JavaScript function.

    Create a partial view named '_LoadingPartial' with the bootstrap spinner as shown below. (Other spinners / progress images can also be used instead of the bootstrap spinner.)

    @{ 
       <div class="d-flex justify-content-center">
            <div class="spinner-border text-primary mb-3"
                 style="width: 3rem; height: 3rem; display: none"
                 role="status" id="loading">
                <span class="sr-only">Loading...</span>
            </div>
        </div> 
     }
    

    Place the partial view tag in the place where the spinner is intended to be displayed. (I have placed it under the 'process' button)

    <partial name="_LoadingPartial" />
    

    I have called the below javascript function in the view page on the 'process' button click event.

     function displayProcessingImage()() {           
            if (document.getElementById("procYrDropdown").value != ""
                && document.getElementById("procMonthDropdown").value != "") {
                document.getElementById("loading").style.display = "block";
            }
        }
    

    The processing image spins gracefully along with 'loading' text when the process button is clicked and hides after the process completes.