您的位置:首页 > Web前端 > JQuery

Integrating jQuery UI and ASP.NET MVC

2013-08-20 00:03 621 查看

 

 

The jQuery UI library is an excellent tool for building dynamic and highly responsive user interfaces. Writing a simple view to showcase its capabilities is no big deal, and this is definitely a great statement about the library itself. For example, if you’re
looking for a tabstrip component—a commonly requested feature—jQuery UI offers a client-side solution that allows you to switch between tabs without causing a full page refresh. If the content of the tab is not static and is available somewhere in the current
DOM, it can be downloaded from a remote location, but the request is sent asynchronously using the classic XMLHttpRequest object. To arrange a tabstrip, you need only to create an ad hoc HTML structure and then call a jQuery UI starter function on the root
element of the tree.

As I mentioned, showcasing jQuery UI is extremely easy, but using it in real-world views and complex pages is a bit more problematic. The biggest issue is not so much the functionality itself, which remains relatively easy to arrange and exploit. If you’re
starting with a blank page, adding jQuery UI is not hard. However, if you have a master page or are modifying an existing master page to support jQuery UI—a very common scenario these days—then be prepared to face some issues. You won’t run into anything that
really prevents you from using jQuery UI effectively and extensively, but you do face some design considerations and some slight restructuring of your server code.

In this article, I’ll show how to modify the standard project template of ASP.NET MVC 2 applications to incorporate jQuery UI functionalities. The final result is the skeleton of an ASP.NET MVC application whose front-end implements a jQuery UI tabstrip.
The final code is only the starting point for a fully AJAX-enabled ASP.NET MVC application.

Setup of the Project

One of the conventions of ASP.NET MVC applications is storing all auxiliary resources, like CSS and images, under the Content folder and all script files under the Scripts folder. These conventions can be changed without affecting any aspects of the run-time
behavior, but I don’t see any reasons to make the change. So let’s start with the default ASP.NET MVC project and assume that the Content folder contains a subdirectory with all the files for the selected jQuery UI theme. Also, let’s assume that all jQuery
UI script files live under the Scripts folder. Figure 1 gives you an idea of the project folder.



Figure 1. The project folder after the first step.

In addition, the site.master file will link the script files for the library. Here’s an excerpt from the master file that shows the actual content of the <head> section:

<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" rel="stylesheet"
type="text/css" />
<link href="../../Content/jq-ui-Themes/sunny/jquery-ui-sunny.css" rel="stylesheet"
type="text/css" />
<script type="text/javascript"
src="../../Scripts/jquery-1.4.1.min.js" />
<script type="text/javascript"
src="../../Scripts/jQueryUI/jquery-ui-1.7.2.custom.min.js" />
</head>

This ends the preliminaries of the project setup. The jQuery UI library is now ready for use.

The Master Page

The default master page is shown in Figure 2. As you can see, it offers a couple of tabs that remain in every view created from the master page. The idea is to transform these static tabs into a more dynamic structure in which tabs are created and managed
via the script code injected by jQuery UI.



Figure 2. The default master page of ASP.NET MVC applications.

The tabs are created using the following code:

<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>

Nicely enough, this HTML structure is semantically correct for jQuery UI to work and doesn’t really need significant changes. The following code is a slightly edited version that includes a couple more tabs plus some extra information about the title string
to display:

<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home",
new { title="Home Page" }, null)%></li>
<li><%= Html.ActionLink("About", "About", "Home",
new { title = "About" }, null)%></li>
<li><%= Html.ActionLink("Misc", "Demo", "Home",
new { title = "Miscellaneous demos" }, null)%></li>
<li><%= Html.ActionLink("What's up here", "Todo", "Home",
new { title = "Read me" }, null)%></li>
</ul>
</div>

Why is the title string specified as an argument?

When you have a client-side tabstrip activated via script code, the change of the title doesn’t happen automatically. In a classic non-AJAX scenario, every click on a tab causes a new page to be assembled, mixing together master and view. In this process,
you set the page title on the server. You need some script code to update the page title when you switch to another tab, and the string for the title must be passed in some way. The code shown earlier adds the
title attribute to the hyperlink, and this has a double benefit. On one hand, it attaches a tooltip for when the user hovers over the tab, and on the other, it stores the string in a DOM attribute where you can retrieve it programmatically.

Turning Action Links into Tabs

As I mentioned, the menucontainer DIV block you find in the standard ASP.NET MVC master page is just perfect for providing the scaffolding for a jQuery UI tabstrip. All you need to do is attach a bit of script code that runs when each page based
on the master is loaded. You can use jQuery—not jQuery UI—facilities and register a handler for the document’s
ready event. Alternatively, you can use any similar facilities that your AJAX library of choice offers. These days jQuery is pretty popular, and everyone seems to confirm that it will only grow in the future. So here’s the jQuery code you need:

<script type="text/javascript">
$(document).ready(function() {
$("menucontainer").tabs();
});
</script>

Figure 3 shows the new look of the page once it is equipped with jQuery UI.



Figure 3—A jQuery UI tabstrip in lieu of static tabs.

There are a couple of things to notice and understand in more depth. The first regards the home page of the site, and the second is about the title of the page and how it changes when the user moves through the tabs.

The default.aspx Template

In a normal ASP.NET MVC application, you don’t need any default.aspx file. The only exception is when your ASP.NET MVC application is hosted under IIS 6 or under IIS 7 but configured to run in Classic mode (as opposed to Pipeline mode). Under normal circumstances,
the home page of an ASP.NET MVC application results from the composition of the master page with the Index.aspx template. In addition, the
Index method on the Home controller is the default action that determines what the end user sees on her first visit to the site. So what’s this default.aspx template all about?

When you use jQuery UI to power up your ASP.NET MVC site, you need an extra container page where you stuff the DIV block and any related script code for the tabstrip. The
Index method on the Home controller—or whatever action you decide to call to populate your home page—is no longer responsible for the entire home page but only for the content that goes into the tab. More concretely, this means that you need an additional
template and controller action to contain the tabstrip. I decided to call the method
Default, and given the code below, the host view is default.aspx. It goes without saying that you can change this name at your leisure. The implementation of the method
Default, as well as the structure of the default.aspx view, isn’t really rocket science. Here’s how it looks:

public class HomeController : Controller
{
public ActionResult Default()
{
return View();
}
:
}

Similarly, the markup in the default.aspx view is fairly trivial stuff:

<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Nice UI
</asp:Content>

Finally, some changes are required also in the global.asax file; specifically, in the section where the supported routes are defined and registered:

public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {
controller = "Home",
action = "Default",
id = UrlParameter.Optional
}
);
}

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}

As you can see, the default action is now Default in lieu of the standard
Index method. This means that the role and content of the views linked from the tabstrip are different from a standard ASP.NET MVC application.

Let’s have a look at the code of the Index method and related view:

public ActionResult Index()
{
ViewData["Message"] = "Welcome to the <span id=\"hiTitle\">
MVC+jQueryUI</span> template!";
return View();
}

As you can see, there’s nothing special in the Index method and in any of the other methods linked from the tabstrip. A key difference instead lives in the Index.aspx view:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<script type="text/javascript">
$(document).ready(function() {
:
});
</script>

<div>
<table>
<tr>
<td>
<h2><%= ViewData["Message"] %></h2>
<p>
To learn more about ASP.NET MVC visit
<a href="http://asp.net/mvc"
title="ASP.NET MVC Website"> http://asp.net/mvc </a>.
</p>
<p>
To learn more about jQuery UI visit
<a href="http://jqueryui.com"
title="jQuery UI Website"> http://jqueryui.com </a>.
</p>
</td>
<td valign="top">
:
</td>
</tr>
</table>
</div>

The raw content is nearly the same as in the analogous view from the standard project template. A huge difference is that now, with jQuery UI in place and a new default.aspx view around,
Index and any other view linked from the tabstrip are partial views. As a result, they don’t build the entire page and don’t need to inherit from the master page. The
Index view simply returns a chunk of HTML that is merged within the template of the default.aspx view.

The Home tab you see in Figure 3 is associated with the /Home/Index URL, and a similar ASP.NET MVC URL is attached to any tabs. When the user clicks, the tabstrip jQuery UI component connects to the URL via AJAX and downloads the response. Next, the response
is inserted—as is—in the current DOM in the subtree that represents the content of the clicked tab. For this precise reason, the URL can’t return a full page view but must be limited to returning a partial view. In terms of ASP.NET MVC programming, this simply
means that you have to adjust the view so that it returns a chunk of HTML. You obtain this by simply removing dependencies on the master page. Alternatively, you can achieve the same result by writing a user control and returning it via
PartialView from the method, as shown here:

public ActionResult Index()
{
:
return PartialView(); // assumed index.ascx under Views
}

In summary, when you switch to a jQuery UI template you must assume a host that is a classic ASP.NET MVC page and one partial view for each tab. The markup for the tab is automatically downloaded via AJAX, and the content is cached as any other Web resource.

Note that in this jQuery UI template, if you request /Home/Index from the address bar, you get a script error or a scanty, black-and-white HTML page, depending on the user’s settings for scripting within the browser.

Changing the Page Title

In classic ASP.NET MVC, when tabs are just plain links to navigate to another page, each view can easily set the page title. When the user tabs to Home/About, the About view quite simply sets the page title using any tools available—a piece of script code,
a placeholder from the master page, or even the API offered by the code-behind
ViewPage class.

How would you set the page title instead when the Home/Index (and similar) URLs are just endpoints for partial views? In this case, you rely on the tabstrip API and intercept the user’s clicking that changes the selection to a new tab. Because this script
code is common to all jQuery UI based pages, you can insert it into the master page or into the default.aspx host page. Here’s the code you need:

<script type="text/javascript">
$(document).ready(function() {
$("menucontainer").tabs();
$("menucontainer").bind( 'tabsselect',
function( event, ui ) {
document.title = ui.tab.title;
}
);
});
</script>

As you saw earlier, the first call just sets up the tabstrip. The second call registers an event handler for the
tabsSelect event fired by the jQuery UI tabstrip. The event is fired whenever the user changes the selection. The code to run in this case is specific through the anonymous function parameter. You can see that all it does is set the title of the current
document—the page—to the title property of the currently selected tab. The expression
ui.tab is used to refer to the root of the DOM subtree that represents the tab. The value assigned to the
title attribute is the same value you passed in as the title attribute when you created the link for the tab. In other words, the same string is used for both the tooltip of the tab and for the page title when that tab is selected.

Summary

With the jQuery library gaining momentum and being fully embraced by Microsoft, the jQuery UI library is also destined to be used more and more. ASP.NET MVC represents the new frontier of ASP.NET development, and it is strongly characterized by the control
it provides over markup. Control over markup means control over every bit of HTML—but also over the script code being emitted to the browser. For this reason, the combination of ASP.NET MVC and jQuery has already been welcomed as a powerful duo. The jQuery
UI library just adds more spice to an already sapid dish.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: