0

The current interaction behavior is that after I click submit the form, it should have delayed time with spinner and success message but they're still not showing only modal close in setTimeout() inside showSuccess()

I have modal overlay after modal-footer and inside modal-content

<div id="modalOverlay" class="position-absolute top-0 start-0 w-100 h-100 d-flex flex-column justify-content-center align-items-center" style="z-index: 1000;">
    <div id="loadingSpinner" class="spinner-border text-primary d-none" role="status">
        <span class="visually-hidden">Loading...</span>
    </div>

    <div id="successMessage" class="alert alert-success mt-3 d-none" role="alert">
        Added Successully!
    </div>
</div>

function hideAddModal() {
    document.getElementById("modalOverlay").style.pointerEvents = "none";
    $("#addModal").modal("hide");
    $(".modal-backdrop").remove();
}
function showSpinner() {
    $("#loadingSpinner").removeClass("d-none");
    $("#successMessage").addClass("d-none");
    document.getElementById("modalOverlay").style.pointerEvents = "auto";
}
function showSuccess() {
    $("#loadingSpinner").addClass("d-none");
    $("#successMessage").removeClass("d-none");
    document.getElementById("modalOverlay").style.pointerEvents = "auto";

    setTimeout(function () {
        hideAddModal();
        $("#successMessage").addClass("d-none");
    }, 1000)
}

Below here is code snippet of submit function after button is triggered

bool isInserted = await InsertStored(value);
if (isInserted)
{
    BindGridView(); 
    Debug.WriteLine("Registering script to hide modal");
    ScriptManager.RegisterStartupScript(this, GetType(), Guid.NewGuid().ToString(),
    @"
    showSpinner();
    setTimeout(function() {
        showSuccess();
    }, 500);
    ",
    true);
}
else
{
    // Another ScriptManager to show alert error message
}

** EDIT ***

Everything seems to work. I use OnClientClick() on spinner but showSuccess() doesn't work. Only hideAddModal() works.

2 Answers 2

0

Keep in mind the page life cycle. There no requirement to "hide" the existing popup, since when the page returns to the client side, then the whole page is refreshed, JavaScript engine re-sets all variables, and re-starts.

And if you modify a control, or inject script? Such code is only making changes to the copy of the web page up on the server when code behind runs. Thus, code behind when changing a text box, or injecting script will not be seen by the client side until such time that a 100% of the server side code is completed. So, script injection into a page will not be seen by the end user until the page life cycle completes, and the server page with changes to contorls, or with injected script travels back to the client side.

We thus can take advantage of above since when the new page is returned from the server, then our dialog will automatic hide and revert back to its original state. Hence, we really only need to "inject" a confirm/done dialog.

So, say this sample markup. I'm using a jQuery.UI dialog, but the concept and approach is the same for any type of dialog display you use.

So, when we click the button then we need to run client side code first to display the dialog (we can't use script injection, since that will only appear after all the server side code is done processing). Since buttons have both a client side event, and server side, then we simply specify both events for our button click. The client side code can thus display the dialog/message while we wait for the server side code to complete.

Hence, this markup:

        <asp:Button ID="cmdProcess" runat="server" Text="Process data"
            CssClass="myshadow"
            OnClick="cmdProcess_Click"
            OnClientClick="showwait();return true"                
            />

        <div id="mypoparea" style="display:none">

             <img id="myimage" src="" width="32"
                 style="float:left"/>
                 <label id="msgarea" style="float:left;margin-left:10px;margin-top:4px">
                 </label>
        </div>

        <script>
            function showwait() {
                $("#myimage").prop("src","/Content/wait2.gif")
                $("#msgarea").text("Processing data - wait")
                var myDialog = $("#mypoparea")
                myDialog.dialog({
                    modal: true,
                    title: "Working", closeText: "",
                    dialogClass: "dialogWithDropShadow"

                });
            }

            function showdone() {
                $("#myimage").prop("src", "/Content/Approved80.png")
                $("#msgarea").text("Process completed")
                var myDialog = $("#mypoparea")
                myDialog.dialog({
                    modal: true,
                    title: "Done", closeText: "",
                    dialogClass: "dialogWithDropShadow",
                    buttons: {
                        Ok: function () {
                            myDialog.dialog('close')
                        }
                    }
                });
            }
        </script>

So, a jQuery.UI dialog simply displays a "div" as a dialog.

So, now our code behind can be this:

    protected void cmdProcess_Click(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(3000); // fake a long process

        string sJava = "showdone()";
        ScriptManager.RegisterStartupScript(this, this.GetType(),"mypop",sJava,true);
    }

And the result is thus this:

enter image description here

So, note how the original dialog requires no code to hide, since when the fresh page returns from the server, it will revert back to it's original state. Hence, we only have to inject/display the 2nd dialog to show completion. And I suppose I could make one "general routine" in which you pass the "image", the title, and the message text to a client side JavaScript routine (and thus having a nice re-usable dialog box system). However, the above is a good proof of concept here as to how this works, and it leverages the page lifecycle to hide the original "wait" dialog.

Sign up to request clarification or add additional context in comments.

Comments

0

Your issue is caused by calling hideAddModal() too soon inside showSuccess(), which closes the modal before the spinner or success message can render.

Solution:

1. Delay hiding the modal longer:

enter image description here

2. Give spinner time to show before success:

enter image description here

This ensures users can actually see the spinner and success message before the modal closes.

1 Comment

showSpinner() works however only hideAddModal(); runs in showSuccess() so when submitted spinner displays but then after 2 timeout() modal close together with spinner

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.