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/.