Nil Pun
Nil Pun

Reputation: 17373

MVC Jquery Progress Spinner On Submit

Greetings,

Could anyone help me how to implement the Jquery Progress Spinner with ASP.NET MVC on button click, please

Thankyou in advance.

Upvotes: 3

Views: 10831

Answers (7)

Fuzzybear
Fuzzybear

Reputation: 1418

Late to the party for this question but anyone looking for a NONE AJAX approach or using the html.BeginForm then this answer here helped me.

Activating loading animation by Html.BeginForm submission

Summary of the answer if removed or link breaks:

First, add an ID to the form so you can grab it using JQuery:

@using (Html.BeginForm("SData", "Crawl", FormMethod.Post, new { id = "myform" }))
{
    // the form
}

Next, add a Javascript event handler to intercept the form submission and display the loading GIF.

$("#myform").submit(function(e) {
    $("#myLoadingElement").show();
});

Upvotes: 0

Keith Ketterer
Keith Ketterer

Reputation: 461

You can use ajaxStart/ajaxStop. jQuery 1.8 example:

$(document).ready(function () {
        $("#btnShowSpinner").click(ajaxToExecute); // wire up click event for the button
        (function () { $("#loading").hide(); })(); // hide the spinner initially
        $(document).ajaxStart(function () { $("#loading").show(); }); // show spinner when ajax request executes
        $(document).ajaxStop(function () { $("#loading").hide(); });// show spinner when ajax request completes
});

In your page markup add a div containing the spinner to display to the user:

<input id="btnShowSpinner" type="button" value="Show Spinner" />
<div id="loading"><img src="spinner.gif" /></div>

Ajax call:

function ajaxToExecute() {
    $.ajax({
        cache: false,
        type: "POST",
        url: myURL
        data: { "id": id},
        success: function (data) {
            updateDiv.html(data);
        },
        error: function (xhr, ajaxOptions, thrownError) {
                   alert('Request failed.\nError: ' + thrownError);
               }
    });
}

This design would also allow reuse of the spinner for any other ajax requests on the page.

Upvotes: 0

ghiscoding
ghiscoding

Reputation: 13204

So I found this question which is exactly what I was looking for, but I didn't like the concept of the official answer...why? Well using AJAX to submit the Form is nice but you lose the power of ASP MVC and his concept of returning a @model to the View and by using AJAX you'll also have to change a lot of code to return AJAX/JSON response (changing return of ActionResult to JsonResult, etc...) inside the Controller. I didn't want to lose the output of ActionResult with return View(model) as it comes very handy (especially with the jQuery Validation hooked to the model)... So I came up with using the following instead:

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    ...

    <div class="form-group">
        <button id="saveBtn" type="submit" class="btn btn-primary">Save</button>
        @Html.ActionLink("Back to List", "Index")
    </div>
}

@section Scripts {
    <!-- jQuery ASP Validation -->
    @Scripts.Render("~/Scripts/jqueryval")

    <script type="text/javascript">
        $(document).ready(function () {
            // clear error summary from inside our global variable (defined in _layout view)
            window.App.errorSummary = {};

            // Attach click handler to the submit button
            // from there, attach a spinner but only if no error summary are showing
            $('#saveBtn').click(function () {
                // has to be inside a timer else it would be triggered too late
                setTimeout(function () {
                    if (window.App.errorSummary.numberOfInvalids < 1) {
                        // your spinner here... in my case spinner.js
                    }
                }, 50);
            });
        });
    </script>
}

and you also have to extend the jQuery Validator object but is preferable to extend it inside your _Layout View, and from there my code looks like this:

window.App = {
    baseUrlArea: '@((ViewContext.RouteData.Values["area"] == null) ? "" : ViewContext.RouteData.Values["area"])',
    baseUrl: '@Url.Content("~/")',
    language: '@((ViewContext.RouteData.Values["language"] == null) ? "en" : ViewContext.RouteData.Values["language"])',
    controller: '@ViewContext.RouteData.Values["controller"]',
    action: '@ViewContext.RouteData.Values["action"]',
    errorSummary: {}
};

$(document).ready(function () {
    // extend the jquery validator object to keep track of error summary 
    // save summary inside the global (window.App) variable
    if (typeof $.validator !== "undefined") {
        $.validator.setDefaults({
            showErrors: function (errorMap, errorList) {
                window.App.errorSummary.numberOfInvalids = this.numberOfInvalids();
                window.App.errorSummary.errorMap = errorMap;
                window.App.errorSummary.errorList = errorList;

                $("#summary").html("Your form contains "
                  + this.numberOfInvalids()
                  + " errors, see details below.");
                this.defaultShowErrors();
            }
        });
    }            
});

You probably think, why bother with the numberOfInvalids? Well not doing so would make the spinner show up when click on Save button, though we only want it to show when Validation Error Summary is empty...make sense? So, there you go, we now regain full power of ASP/MVC with jQuery validation! And our spinner is showing only when it has to show. Sweet!!! :)

Upvotes: 2

Nil Pun
Nil Pun

Reputation: 17373

I ended up using these great resources:

  1. http://contextllc.com/dev_tools/jQuery/showLoading/latest/jquery.showLoading.example.html
  2. http://ajaxload.info/

Easy and simple.

Upvotes: 2

Muhammad Adeel Zahid
Muhammad Adeel Zahid

Reputation: 17784

$.ajax({
type="get",
url="someurl.html",
dataType:"html",
beforeSend(jqXHR, settings)
{
     //append spinner image to some html element
},
success:function(data)
{
    //manipulate data
},
Complete:(jqXHR, textStatus)
{
    //Remove spinner from the page
}
});

Upvotes: 2

Michiel Cornille
Michiel Cornille

Reputation: 2097

Let's say you had 500 Items (Files/whatever) to handle during progress,...

You'd have to handle every item individually.

then iterate over all items and:

  • Make an $.ajax call to a the 'Handle' action in your ItemController that processes a single item
  • return a json result code
  • if ok, move the jquery progress thing up one step
  • if failed, either do the next one, or cancel the entire process (according to your requirements)

Upvotes: 0

Related Questions