Busy Indicator

8 posts, 2 answers
  1. Joel
    Joel avatar
    209 posts
    Member since:
    Jun 2018

    Posted 08 Sep 2020 Link to this post

    When I hit a button that takes a long time I'd like to show a Busy Indicator that disables the form... like what you have for your other products.  Any idea how I would accomplish this for ASP.NET Core 3.1 MVC?
  2. Neli
    Admin
    Neli avatar
    424 posts

    Posted 11 Sep 2020 Link to this post

    Hello Joel,

    I would suggest you take a look at the kendo.progress method linked below. It is designed to be used during asynchronous remote data requests:

    - https://docs.telerik.com/kendo-ui/api/javascript/ui/ui/methods/progress

    I hope the provided suggestion will be suitable for your scenario.

    Regards,
    Neli
    Progress Telerik

    Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

  3. Joel
    Joel avatar
    209 posts
    Member since:
    Jun 2018

    Posted 11 Sep 2020 in reply to Neli Link to this post

    I'm trying to figure this out using ASP.NET Core MVC 3.1 with cshtml pages.  I don't get it. 

    This is my (incorrect) attempt:

    $(document).ready(function () {
     
        $('#btnSave').on('click',
            function (event) {
     
                kendo.ui.progress(#form, true);
                $('#form').submit();
     
            });
    });

    This doesn't recognize the kendo namespace. The scripts should be there

    My _Layout page header:

    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@Glossary.Company Portal - @ViewData["Title"]</title>
     
        <environment include="Development">
            <link rel="stylesheet" href="~/lib/bootstrap/css/bootstrap.css" />
            <link rel="stylesheet" href="~/css/site.css" />
        </environment>
        <environment exclude="Development">
                  asp-fallback-href="~/lib/bootstrap/css/bootstrap.min.css"
                  asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
            <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
        </environment>
        <link href="https://kendo.cdn.telerik.com/2020.2.617/styles/kendo.bootstrap-v4.min.css" rel="stylesheet" type="text/css" />
        <link rel="stylesheet" type="text/css" href="~/css/GsiWebPortalBootstrapTheme.css" />
    </head>

     

    I have this script that disables the buttons.  Instead of doing this, I'd like the #form to have the spinner:

    <h2>@Model.Title</h2>
    <h3>@Model.Subtitle</h3>
    <h4>@Model.Message</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Edit" asp-all-route-data="routeKeys" id="form" >
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <input type="hidden" asp-for="Item.Id" />
                <div class="form-group">
                    <label asp-for="Item.FirstName" class="control-label"></label>
                    <input asp-for="Item.FirstName" class="form-control" />
                    <span asp-validation-for="Item.FirstName" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Item.LastName" class="control-label"></label>
                    <input asp-for="Item.LastName" class="form-control" />
                    <span asp-validation-for="Item.LastName" class="text-danger"></span>
                </div>
     
                @if (ProfileService.IsInRole(SecurityRoles.Admin) &&
                     !isManageSelf)
                {
                    <div class="form-group">
                        <label asp-for="Item.Status" class="control-label"></label>
                        <br />@(Html.Kendo().DropDownListFor(x => x.Item.CurrentStatusId)
                                    .DataTextField("Name")
                                    .DataValueField("Id")
                                    .DataSource(source =>
                                    {
                                        source.Read(read =>
                                        {
                                            read.Action("GetStatuses", "Users")
                                                .Data("getData");
                                        });
                                    }).HtmlAttributes(new { style = "width: 100%" }))
                    </div>
                    <div class="form-group">
                        <label asp-for="Item.Role" class="control-label"></label>
                        <br />@(Html.Kendo().DropDownListFor(x => x.Item.CurrentRoleId)
                                    .DataTextField("Name")
                                    .DataValueField("Id")
                                    .DataSource(source =>
                                    {
                                        source.Read(read =>
                                        {
                                            read.Action("GetRoles", "Users")
                                                .Data("getData");
                                        });
                                    }).HtmlAttributes(new { style = "width: 100%" }))
                    </div>
                }
                else
                {
                    <input type="hidden" asp-for="Item.CurrentRoleId" />
                    <input type="hidden" asp-for="Item.CurrentStatusId" />
                }
     
                <div class="form-group">
                    @Html.LabelFor(m => m.Item.PrimaryPhone)<br />
                    @(Html.Kendo().MaskedTextBoxFor(m => m.Item.PrimaryPhone)
                          .Mask("(999) 000-0000")
                          .HtmlAttributes(new { style = "width: 100%" }))
                </div>
                <div class="form-group">
                    <label asp-for="Item.PrimaryEmail" class="control-label"></label>
                    <input asp-for="Item.PrimaryEmail" type="email" class="form-control" />
                    <span asp-validation-for="Item.PrimaryEmail" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Item.CountryCode" class="control-label"></label><br />
                    <span asp-validation-for="Item.CountryCode" class="text-danger"></span>
                    @(Html.Kendo().ComboBoxFor(x => x.Item.CountryCode)
                          .Placeholder("Select Country...")
                          .DataTextField("Name")
                          .DataValueField("Code")
                          .Filter(FilterType.Contains)
                          .DataSource(source =>
                          {
                              source.Read(read =>
                              {
                                  read.Action("GetCountries", "Persons");
                              });
                          }).HtmlAttributes(new { style = "width: 100%" }))
                </div>
                <div class="form-group">
                    <input type="submit" value="Save" class="btn btn-primary" id="btnSave" />
                    <input type="button" value="Cancel" onclick="history.go(-1)" class="btn" id="btnCancel" />
                </div>
            </form>
        </div>
    </div>
     
    <script type="text/javascript">
     
        $(document).ready(function () {
     
            $('#btnSave').on('click',
                function (event) {
     
                    $('#btnSave').prop('disabled', true);
                    $('#btnCancel').prop('disabled', true);
                    $('#form').prop('disabled', true);
                    $('#form').submit();
                });
        });
     
        function getData() {
            return @Html.Raw(Model.GetIndexData());
        }
     
    </script>
  4. Neli
    Admin
    Neli avatar
    424 posts

    Posted 16 Sep 2020 Link to this post

    Hello Joel,

    To achieve the desired behavior I would suggest a different approach. 

    With our latest R3 release (2020.3.915), the Loader widget has been introduced. On the following links you will find the Loader Demos and API:

    - https://demos.telerik.com/aspnet-core/loader/index

    - https://docs.telerik.com/kendo-ui/api/javascript/ui/loader#configuration

    Attached you will find a runnable sample containing the Loader and a Form. On a button click, the Loader is displayed and the inputs in the Form are disabled. Once, the loader is hidden, the inputs are enabled again. Below you will find the respective code:

    <script>
        $("#toggle").click(function () {
            var loader = $("#loader").data("kendoLoader");
            loader.show();
            $("#SettingsForm input").attr("disabled", true)
            setTimeout(function () {
                $("#SettingsForm input").attr("disabled", false)
                loader.hide();
            }, 3000)
        })
    </script>

    The attached sample project is using the UI for ASP.NET MVC, but the same approach could be used in ASP.NET Core applications.

    I hope you will find the provided sample and articles helpful.

    Regards,
    Neli
    Progress Telerik

    Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive , special prizes and more, for FREE?! Register now for DevReach 2.0(20).

  5. Joel
    Joel avatar
    209 posts
    Member since:
    Jun 2018

    Posted 29 Sep 2020 in reply to Neli Link to this post

    Thank you for the example.  I'm finally getting back to this.  I took what you gave me and:

    • Started a new asp.net core mvc project
    • Updated the project to 2020.3.915
    • Update the _layout to the same version.
    • Copied your model view 
    • Updated the home page

    Got the example to work. Question:  As I showed in my example, I use a regular form; not a telerik form.  I'll keep working with this because I see its potential.  However, it is not clear from your example how to deviate from the telerik controls.

  6. Answer
    Neli
    Admin
    Neli avatar
    424 posts

    Posted 01 Oct 2020 Link to this post

    Hi Joel,

    As far as I understand, you want to display the Kendo Loader, but on a regular form, instead of the Kendo Form. If this is the case, the approach used to display the Loader with Kendo Form could be used with the regular form as well. When the submit button of the form is clicked you could show the Loader and disable the form fields. On the success of submitting the form, you could hide the Loader again and proceed depending on the project requirements. 

    The Dojo example linked here demonstrates the displaying of the Kendo Loader on submitting a standard form.

    I hope this helps.

    Regards,
    Neli
    Progress Telerik

    Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive, special prizes, and more, for FREE?! Register now for DevReach 2.0(20).

  7. Joel
    Joel avatar
    209 posts
    Member since:
    Jun 2018

    Posted 01 Oct 2020 in reply to Neli Link to this post

    Yes, I got this working.  This is MVC so I went with "InfiniteSpinner" so it'd spin until the Controller reloads the form.  Thanks.

    I was hoping that the loader magically disabled the form fields like your other (WPF/Silverlight) busy indicator but that isn't the case.

    Loader:

    <h2>@Model.Title</h2>
    <h3>@Model.Subtitle</h3>
    <h4>@Model.Message</h4>
    @(Html.Kendo().Loader()
        .Name("loader")
        .Size(LoaderSize.Large)
        .Type(LoaderType.InfiniteSpinner)
        .Visible(false))
    <hr />

    Form Definition:

    <form name="form" asp-action="Create" asp-all-route-data="routeKeys" onsubmit="onSubmit()">
    ...

    Script:

    <script>
     
        function onSubmit(e) {
     
            $("#name").attr("disabled", true);
            $("#maximumUserCount").attr("disabled", true);
            $("#Item_TwoFactorEnabled").attr("disabled", true);
            $("#licenseActivationTimestamp").attr("disabled", true);
            $("#licenseRenewalTimestamp").attr("disabled", true);
            $('#btnSave').attr('disabled', true);
            $('#btnCancel').attr('disabled', true);
     
            $("#loader").data("kendoLoader").show();
            //$('#form').submit();
        }
     
    </script>

     

  8. Answer
    Neli
    Admin
    Neli avatar
    424 posts

    Posted 06 Oct 2020 Link to this post

    Hi Joel,

    I am glad to hear that the provided suggestion was helpful and you manage to resolve the issue. Thank you for the feedback and that you have shared your solution with the community. I am sure it could be helpful to someone else in the future who has a similar scenario. 

    Regards,
    Neli
    Progress Telerik

    Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive, special prizes, and more, for FREE?! Register now for DevReach 2.0(20).

Back to Top