Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using Bootstrap Dialogs in ASP.NET MVC

0.00/5 (No votes)
4 Jan 2016 1  
This tip describes an approach to use Bootstrap dialogs in ASP.NET MVC.

Introduction

There are no standards of how to use bootstrap dialogs in ASP.NET MVC.

Often, many questions appear on a phase of implementation:

  • How to create dialogs?
  • Where dialogs should be placed in HTML?
  • How to fill dialogs with dynamic information?
  • How to subscribe to dialog events?

This tip gives an approach to organize and use bootstrap dialogs effectively.

Utility Function

Let’s create a utility function which will be used to create Bootstrap Dialogs.

DialogUtils = {
    ShowDialog: function(dialogOptions) {
        var container = $("[data-dialog-container=\"" + dialogOptions.url + "\"]");
        /* Check is dialog already exists to prevent double loading */
        if (container.length) {
            return;
        }
        /* Create new container for dialog url */
        var newContainer = $("<div></div>");
        newContainer.attr("data-dialog-container", dialogOptions.url);
        $("body").append(newContainer);
        container = newContainer;
        /* Load dialog into container */
        $.post(dialogOptions.url, dialogOptions.data, function(response, status, xhr) {
            if (status == "error") {
                console.error("Couldn't load dialog " + dialogOptions.url + 
				" due to error: " + xhr.statusText);
                return;
            }
            container.html(response);
            var dialog = $('.modal', container);
            dialog.modal('show');
            /* Enable dialog result handlers */
            dialog.on('hidden.bs.modal', function() {
                if (dialog.data("dialog-result") != undefined) {
                    var dialogResultHandler = "on" + dialog.data("dialog-result");
                    if (dialogOptions[dialogResultHandler] !== undefined) {
                        dialogOptions[dialogResultHandler](dialog);
                    }
                }
                container.remove();
            });
        });
    }
};

And the usage is:

DialogUtils.ShowDialog({
      url: "@Url.Action("SubmitPaymentConfirmation")",
      data: $("#SubmitPayment").serialize(),
      onConfirm: function () {
          $("#SubmitPayment").submit();
      },
      onConfirmAndPrint: function () {
          $("#Print").val("true"); //some hidden field
          $("#SubmitPayment").submit();
      }
  });

This function takes as a parameter dialogOptions which contains the following properties:

  • url: address of action which provides dialog HTML
  • data: parameter of action
  • onConfirm, onConfirmAndPrint – callbacks which are invoked when dialog is closed with specific state (for example: Confirm, ConfirmAndPrint, etc.)

For callbacks to work dialogs should be closed with specific state. By default, bootstrap doesn’t have any, so the wrapper function for modal.hide would be required:

/* override original bootstrap modal function to set the dialog result on hide. 
Usage: modal('hide', 'result') */
$(function () {
    var originalModal = $.fn.modal;
    $.fn.modal = function(option, result) {
        if (option == 'hide' && typeof result == 'string') {
            var $this = $(this);
            $this.data("dialog-result", result);
            arguments[1] = null;
        }
        originalModal.apply(this, arguments);
    };
});

Now the dialog template should contain triggers which close dialog with specific state:

@model Dialogs.Models.SubmitPaymentConfirmation
@{
    Layout = null;
}
<div class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" 
                data-dismiss="modal" aria-label="Close">
		<span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">Payment Confirmation</h4>
            </div>
            <div class="modal-body">
                <div class="row">
                    <label class="col-md-6 text-nowrap text-right">Amount:</label>
                    <span>@Html.DisplayFor(model => model.Amount)</span>
                </div>
                <div class="row">
                    <label class="col-md-6 text-nowrap text-right">Name On Card:</label>
                    <span>@Html.DisplayFor(model => model.NameOnCard)</span>
                </div>
                <div class="row">
                    <label class="col-md-6 text-nowrap text-right">CVV:</label>
                    <span>@Html.DisplayFor(model => model.CreditCardCvv2)</span>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default btn-primary" 
		onclick="$(this).closest('.modal').modal('hide', 'Confirm')">
                    <span class="glyphicon glyphicon-ok"></span> CONFIRM
                </button>
                <button type="button" class="btn btn-default" 
		onclick="$(this).closest('.modal').modal('hide', 'ConfirmAndPrint')">
                    <span class="glyphicon glyphicon-ok-circle"></span> CONFIRM AND PRINT
                </button>
                <button type="button" class="btn btn-default" data-dismiss="modal">
                    <span class="glyphicon glyphicon-remove-circle"></span> CANCEL
                </button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div>
<!-- /.modal -->

You can see that Confirm and ConfirmAndPrint buttons contain handlers which close the dialog with specific state.

The last thing to say is dialog represents a separate action in the controller:

public ViewResult SubmitPaymentConfirmation(SubmitPaymentConfirmation paymentPageModel)
{
            return View("SubmitPaymentConfirmation", paymentPageModel);
}

Explanation

For each dialog, a new container is created and attached to body. Dialog is loaded into container by url provided in the parameter. When dialog is closed, its close state is written to dialog-result data field and callback with this state is executed. After that, container with dialog is removed. Dialog template is stored in a separate file and may contain scripts/styles assuming they do not correlate with page content.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here