Search code examples
asp.nettoastr

Toastr notifications at the redirect from modal window


I'm hoping to use Toastr in ASP.net MVC5 with modal windows. Now, when I click the button on modal window, I'm sending data to one of my controllers via AJAX call and get redirected to the home page. Unfortunately, Toastr notifications are not working in this scenario. In dev console I can see the notification when using break points, though. But with redirect it just doesn't have any time to be seeing on the page. Any suggestions how to make it stay and be visible at the redirect to another page? I'm using Toastr in .done and .fail methods of the AJAX call.

The modal window in the html file:

               <div class="modal fade" id="myConfirmModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header">
                                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                            </div>
                            <div id="WorkflowConfirmModal" class="modal-body">
                                Are you sure you want to submit this transaction?
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-primary" id="myID" data-val="@Url.Action("myAction", "myController", null)" data-redirect="@Url.Action("Index", "Home")">Yes</button>
                                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                            </div>
                        </div>
                    </div>
                </div>

The AXAJ call in the separate .js file:

    $('#myID').on("click", function () {
    var reviewData = {
        //... my data here
    };
    $.ajax({
            url: $('#myID').data('val'),
            type: 'POST',
            dataType: 'json',
            data: reviewData,
            success: function (data) {
                if (data.success == true) {
                    window.location.href = $('#myID').data('redirect');
                } else {
                    $('#myConfirmModal').modal('hide');
                    bootbox.alert(
                        "<h4>Submit Errors</h4>" +
                        "<hr><p>" + data.errors + "</p>");
                }
            }
        })
        .done(function () {
            toastr.success("Success!");
        })
        .fail(function () {
            toastr.error("Something went wrong.");
        });
});

Solution

  • Your browser is off to the races when you issue that window.location command so you have two options:

    1. Route a value ALLLL the way through your controller back into your reloaded view and kick the toastr off there. (This sucks, don't do this)

    2. Restructure your JS so that your window.location call happens after the toastr hide event finishes. something like so :

      toastr.error("Content", "Title", {onHidden : function() { alert("do a redirect inside this function");}});

    chained Example for first time poster:

    var n = $('#n').val();
    $('#success').click(function () {toastr.success( $('#g').val(), n, { onHidden : function() { toastr.warning( $('#l').val(), n, { onHidden : function() { toastr.error( $('#r').val(), n, {onHidden : function() { alert( $('#d').val());}, "timeOut": "900"});}, "timeOut": "900"});}, "timeOut": "900"});   });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css"><input type="hidden" id="n" value="Never Gonna"><input type="hidden" id="g" value="give you up"><input type="hidden" id="r" value="run around"><input type="hidden" id="l" value="let you down"><input type="hidden" id="d" value="and desert you">
    
    <input type="button" value="Click Me" id="success" />

    Example for first option requested by user:

    View where BTN is pushed (just append a query string param when you call the controller action - here I am just sending a request to HOME/Index and appending ConfirmS = true as a param):

    <div class="btn btn-primary" onclick="location='/?ConfirmS=true'"> GO </div>
    

    Home Controller Index Action method (add a nullable param and if it exists and is true in this case then set a viewbag param to send to our view)

        public ActionResult Index(bool? ConfirmS)
        {
            if (ConfirmS.HasValue && ConfirmS.Value) { ViewBag.ConfirmSubmitMessage = "weeeee"; }
    
            return View();
        }
    

    Home Index View (check if your viewbag property exists and if it does then do something like trigger a toastr alert):

    @if (ViewBag.ConfirmSubmitMessage != null)
    {
        <script>alert('@ViewBag.ConfirmSubmitMessage');</script>
    }