1 /* ****************************************************************************
\r
3 * Copyright (c) Microsoft Corporation. All rights reserved.
\r
5 * This software is subject to the Microsoft Public License (Ms-PL).
\r
6 * A copy of the license can be found in the license.htm file included
\r
7 * in this distribution.
\r
9 * You must not remove this notice, or any other, from this software.
\r
11 * ***************************************************************************/
\r
13 namespace System.Web.Mvc.Ajax {
\r
15 using System.Collections.Generic;
\r
16 using System.ComponentModel;
\r
17 using System.Diagnostics.CodeAnalysis;
\r
18 using System.Globalization;
\r
20 using System.Web.Mvc;
\r
21 using System.Web.Mvc.Html;
\r
22 using System.Web.Mvc.Resources;
\r
23 using System.Web.Routing;
\r
25 public static class AjaxExtensions {
\r
26 private const string LinkOnClickFormat = "Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), {0});";
\r
27 private const string FormOnClickValue = "Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));";
\r
28 private const string FormOnSubmitFormat = "Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), {0});";
\r
29 private const string _globalizationScript = @"<script type=""text/javascript"" src=""{0}""></script>";
\r
31 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, AjaxOptions ajaxOptions) {
\r
32 return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, ajaxOptions);
\r
35 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions) {
\r
36 return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
\r
39 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
40 return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
\r
43 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
\r
44 return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
\r
47 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
48 return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
\r
51 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, AjaxOptions ajaxOptions) {
\r
52 return ActionLink(ajaxHelper, linkText, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
\r
55 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) {
\r
56 return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
\r
59 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
60 RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
\r
61 Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
\r
62 return ActionLink(ajaxHelper, linkText, actionName, controllerName, newValues, ajaxOptions, newAttributes);
\r
65 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
\r
66 return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
\r
69 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
70 if (String.IsNullOrEmpty(linkText)) {
\r
71 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
\r
74 string targetUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
\r
76 return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
\r
79 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
80 RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
\r
81 Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
\r
82 return ActionLink(ajaxHelper, linkText, actionName, controllerName, protocol, hostName, fragment, newValues, ajaxOptions, newAttributes);
\r
85 public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
86 if (String.IsNullOrEmpty(linkText)) {
\r
87 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
\r
90 string targetUrl = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
\r
92 return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, ajaxOptions, htmlAttributes));
\r
95 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, AjaxOptions ajaxOptions) {
\r
96 string formAction = ajaxHelper.ViewContext.HttpContext.Request.RawUrl;
\r
97 return FormHelper(ajaxHelper, formAction, ajaxOptions, new RouteValueDictionary());
\r
100 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, AjaxOptions ajaxOptions) {
\r
101 return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, ajaxOptions);
\r
104 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions) {
\r
105 return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
\r
108 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
109 return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
\r
112 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
\r
113 return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
\r
116 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
117 return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
\r
120 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, AjaxOptions ajaxOptions) {
\r
121 return BeginForm(ajaxHelper, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
\r
124 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) {
\r
125 return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
\r
128 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
129 RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
\r
130 Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
\r
131 return BeginForm(ajaxHelper, actionName, controllerName, newValues, ajaxOptions, newAttributes);
\r
134 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
\r
135 return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
\r
138 public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
140 string formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
\r
141 return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
\r
144 public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, AjaxOptions ajaxOptions) {
\r
145 return BeginRouteForm(ajaxHelper, routeName, null /* routeValues */, ajaxOptions, null /* htmlAttributes */);
\r
148 public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions) {
\r
149 return BeginRouteForm(ajaxHelper, routeName, (object)routeValues, ajaxOptions, null /* htmlAttributes */);
\r
152 public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
153 Dictionary<string, object> newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes);
\r
154 return BeginRouteForm(ajaxHelper, routeName, new RouteValueDictionary(routeValues), ajaxOptions, newAttributes);
\r
157 public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
\r
158 return BeginRouteForm(ajaxHelper, routeName, routeValues, ajaxOptions, null /* htmlAttributes */);
\r
161 public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
162 string formAction = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
\r
163 return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
\r
166 private static MvcForm FormHelper(this AjaxHelper ajaxHelper, string formAction, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
167 TagBuilder builder = new TagBuilder("form");
\r
168 builder.MergeAttributes(htmlAttributes);
\r
169 builder.MergeAttribute("action", formAction);
\r
170 builder.MergeAttribute("method", "post");
\r
171 builder.MergeAttribute("onclick", FormOnClickValue);
\r
172 builder.MergeAttribute("onsubmit", GenerateAjaxScript(GetAjaxOptions(ajaxOptions), FormOnSubmitFormat));
\r
174 if (ajaxHelper.ViewContext.ClientValidationEnabled) {
\r
175 // forms must have an ID for client validation
\r
176 builder.GenerateId(ajaxHelper.ViewContext.FormIdGenerator());
\r
179 ajaxHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
\r
180 MvcForm theForm = new MvcForm(ajaxHelper.ViewContext);
\r
182 if (ajaxHelper.ViewContext.ClientValidationEnabled) {
\r
183 ajaxHelper.ViewContext.FormContext.FormId = builder.Attributes["id"];
\r
189 public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper) {
\r
190 return GlobalizationScript(ajaxHelper, CultureInfo.CurrentCulture);
\r
193 [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "ajaxHelper",
\r
194 Justification = "This is an extension method")]
\r
195 public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper, CultureInfo cultureInfo) {
\r
196 return GlobalizationScriptHelper(AjaxHelper.GlobalizationScriptPath, cultureInfo);
\r
199 private static MvcHtmlString GlobalizationScriptHelper(string scriptPath, CultureInfo cultureInfo) {
\r
200 if (cultureInfo == null) {
\r
201 throw new ArgumentNullException("cultureInfo");
\r
204 string src = VirtualPathUtility.AppendTrailingSlash(scriptPath) + cultureInfo.Name + ".js";
\r
205 string scriptWithCorrectNewLines = _globalizationScript.Replace("\r\n", Environment.NewLine);
\r
206 string formatted = String.Format(CultureInfo.InvariantCulture, scriptWithCorrectNewLines, src);
\r
208 return MvcHtmlString.Create(formatted);
\r
211 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions) {
\r
212 return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
\r
213 new Dictionary<string, object>());
\r
216 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
217 return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
\r
218 ObjectToCaseSensitiveDictionary(htmlAttributes));
\r
221 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
\r
222 return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions,
\r
223 new Dictionary<string, object>());
\r
226 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
227 return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions, htmlAttributes);
\r
230 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions) {
\r
231 return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions,
\r
232 new Dictionary<string, object>());
\r
235 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
236 return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, ObjectToCaseSensitiveDictionary(htmlAttributes));
\r
239 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
240 return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, htmlAttributes);
\r
243 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions) {
\r
244 return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
\r
245 new Dictionary<string, object>());
\r
248 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
\r
249 return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
\r
250 ObjectToCaseSensitiveDictionary(htmlAttributes));
\r
253 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
\r
254 return RouteLink(ajaxHelper, linkText, routeName, routeValues, ajaxOptions, new Dictionary<string, object>());
\r
257 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
258 if (String.IsNullOrEmpty(linkText)) {
\r
259 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
\r
262 string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
\r
264 return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
\r
267 public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
268 if (String.IsNullOrEmpty(linkText)) {
\r
269 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
\r
272 string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, hostName, fragment, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
\r
274 return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
\r
277 internal static string InsertionModeToString(InsertionMode insertionMode) {
\r
278 switch (insertionMode) {
\r
279 case InsertionMode.Replace:
\r
280 return "Sys.Mvc.InsertionMode.replace";
\r
281 case InsertionMode.InsertBefore:
\r
282 return "Sys.Mvc.InsertionMode.insertBefore";
\r
283 case InsertionMode.InsertAfter:
\r
284 return "Sys.Mvc.InsertionMode.insertAfter";
\r
286 return ((int)insertionMode).ToString(CultureInfo.InvariantCulture);
\r
290 private static Dictionary<string, object> ObjectToCaseSensitiveDictionary(object values) {
\r
291 Dictionary<string, object> dict = new Dictionary<string, object>(StringComparer.Ordinal);
\r
292 if (values != null) {
\r
293 foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(values)) {
\r
294 object val = prop.GetValue(values);
\r
295 dict[prop.Name] = val;
\r
301 private static string GenerateLink(string linkText, string targetUrl, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
\r
302 TagBuilder tag = new TagBuilder("a") {
\r
303 InnerHtml = HttpUtility.HtmlEncode(linkText)
\r
306 tag.MergeAttributes(htmlAttributes);
\r
307 tag.MergeAttribute("href", targetUrl);
\r
308 tag.MergeAttribute("onclick", GenerateAjaxScript(ajaxOptions, LinkOnClickFormat));
\r
310 return tag.ToString(TagRenderMode.Normal);
\r
313 private static string GenerateAjaxScript(AjaxOptions ajaxOptions, string scriptFormat) {
\r
314 string optionsString = ajaxOptions.ToJavascriptString();
\r
315 return String.Format(CultureInfo.InvariantCulture, scriptFormat, optionsString);
\r
318 private static AjaxOptions GetAjaxOptions(AjaxOptions ajaxOptions) {
\r
319 return (ajaxOptions != null) ? ajaxOptions : new AjaxOptions();
\r