Practical .NET

Opening a Dialog Box in an ASP.NET MVC Page

There are lots of benefits to gathering information by opening a dialog box instead of sending your user to another page. Fortunately, jQuery and ASP.NET MVC make it easy to do (and you don't have to worry about offending pop-up blockers).

One of the things desktop developers take for granted is the ability to open a dialog box to gather more data from the user or to allow the user to perform a related task. In a Web application, on the other hand, the default solution is to send the user to another page, then return them to the original page when the task is completed. Fortunately, the jQueryUI dialog plug-in makes it easy to duplicate the desktop dialog box in a Web page (and pop-up blockers don't interfere with it).

That's good because there are lots of benefits to just popping open a dialog. First, with a dialog, the original page is still in the browser so your code behind your dialog still has access to the page's data (and, for the same reason, you can easily update the page with data from the dialog). Second, because you never leave the original page, you avoid any navigation problems related to going away and returning to the original page. Finally, with a dialog your communication with the server involves less overhead than first displaying a completely new page and then re-displaying the original page: your application is more scalable and the user gets a more responsive UX.

To use the jQueryUI dialog plug-in you'll need to add the jQuery and the jQueryUI libraries to your project. For most scenarios where you'll use the dialog plug-in, you'll also need a Web service to deliver the HTML your dialog will display. I've assumed an ASP.NET MVC project for my sample code but, if you're working in an ASP.NET WebForms project, you can use the ASP.NET Web API.

Defining a Page for a jQueryUI Dialog
A View that uses the plug-in needs script tags for both the jQuery and jQueryUI libraries. You'll also need the jQueryUI CSS file to set the appearance of your dialog:

<script src="~/Scripts/jquery-2.1.4.min.js"></script>
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
<link href="~/Content/themes/base/all.css" rel="stylesheet" />

For my case study, I'm assuming a form that displays a customer id and name along with a button that allows the user to update the customer information through a dialog (I assume that the bulk of the page is handling some other information). The page also needs a submit button, of course:

Customer Id: @model.CustomerId
Customer Name: @Html.TextBoxFor(function(m) m.CustomerName)
<input type="button" id="showDialog" value="Revise Customer Information"/>
...rest of the page...
<input type="submit" value="Save Sales Order"/>

The dialog displays HTML stored somewhere on the page so I use a non-displayable div element to hold that HTML. Because I usually retrieve the HTML from the server, my div element starts out with nothing in it:

<div style="display:none" id="divDialog" />

Finally, I need some JavaScript code to wire up my showDialog button to a function that will, eventually, display the dialog (I've called that function DisplayUpdateCustomerDialog):

<script>
  $(function () {
    $("#showDialog").click(function () { DisplayUpdateCustomerDialog(); });
  });
  function DisplayUpdateCustomerDialog()
  {
    //...code for dialog
  }
</script>

Configuring the Dialog's Actions
Inside that DisplayUpdateCustomerDialog function, my first step is to use a set of JavaScript object literals to define the buttons I want to add to the dialog. To work with the jQueryUI dialog, these literals must have a name property (the text that the button will display) and a click property (the function to execute when the user clicks the button). A typical dialog has two buttons: an OK button (which will call a function that does something) and a Cancel button (which will call a function that just closes the dialog), so my usual button definitions look like this:

var applyButton = {
                   text: "OK",
                   click: OKButton
                  }
var cancelButton = {
                    text: "Cancel",
                    click: CloseDialog
                   }

I follow my button definitions with their functions. I typically have my OK button finish by calling the Cancel button's function. Here's a skeleton for the standard functions:

function OKButton() 
{
  //...Do something to update the page from the dialog...
  CloseDialog();
}
function CloseDialog() 
{
  $("#divDialog").dialog("close");
}

Displaying the Dialog
My usual case is that the contents of the dialog box are driven by data that the user has currently entered on the page. As a result, my dialog's HTML needs to be dynamically generated at runtime. I implement that in ASP.NET MVC by making an AJAX call back to the server, passing the relevant data from the page, and building my HTML on the server using a Partial View.

The following JavaScript code in my DisplayUpdateCustomerDialog function will, using the ASP.NET MVC default routing rules, call an action method named DialogHTML in a controller called Home in my application. As part of making the call, I use jQuery to retrieve the current value of an element with its id attribute set to CustomerId and include that data in the request to the server with the name custId. When the HTML comes back from the server, this code inserts the returned HTML into the div element that my dialog uses:

$.get("/Home/DialogHTML/",
      {custId: $("#CustomerId").val()},
      function (dialogHTML) { 
                              $("#divDialog").html(dialogHTML);
                            // ... code to open the dialog 
                            });

On the server, my DialogHTML action method catches the custId value, retrieves any related Customer data, and then passes that data to the Partial View, which generates HTML the dialog will display:

Public Function DialogHTML(custId As String) As ActionResult
  Dim cust As CustomerInfo
  '...retrieve customer information into cust using custId
  Return PartialView("DialogHTML", cust);
End Function

With the HTML retrieved, I'm finally ready to open the dialog box. Following the code that inserts my HTML into the divDialog element, I use jQuery to find that div element and call the dialog plug-in from it, passing an object literal with the settings that control the dialog's display. I think those settings are pretty self-explanatory (well, height and width are in pixels):

$("#divDialog").dialog({
                buttons: [applyButton, cancelButton],
                height: 500,
                width: 500,
                modal: true,
                title: "Revise Customer Data"
            });

Updating the Page
In the OKButton function called from my applyButton, before closing my dialog I typically have to transfer some data from elements in my dialog to elements in my page. This example retrieves data from an element in my dialog's HTML (CustomerNameNew) and uses that value to update an element in the page (CustomerName):

function OKButton() 
{
  var newName;
  newName = $("#CustomerNameNew").val()
  $("#CustomerName").val(newName)
  CloseDialog();
}

And, with that, you can do what desktop developers take for granted: Let your users do something else without having to leave the page.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events