diff --git a/NzbDrone.Web/Helpers/LinkHelper.cs b/NzbDrone.Web/Helpers/LinkHelper.cs index df6d83245..af1438715 100644 --- a/NzbDrone.Web/Helpers/LinkHelper.cs +++ b/NzbDrone.Web/Helpers/LinkHelper.cs @@ -11,6 +11,21 @@ namespace NzbDrone.Web.Helpers { public static class LinkHelper { + public static MvcHtmlString ImageActionLink(this AjaxHelper helper, string imageUrl, object imgAttributes, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) + { + return ImageActionLink(helper, imageUrl, imgAttributes, actionName, null, routeValues, ajaxOptions, htmlAttributes); + } + + public static MvcHtmlString ImageActionLink(this AjaxHelper helper, string imageUrl, object imgAttributes, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) + { + var builder = new TagBuilder("img"); + builder.MergeAttribute("src", imageUrl); + var imgAttributesDictionary = new RouteValueDictionary(imgAttributes); + builder.MergeAttributes(imgAttributesDictionary); + var link = helper.ActionLink("[replaceme]", actionName, controllerName, routeValues, ajaxOptions, htmlAttributes).ToHtmlString(); + return new MvcHtmlString(link.Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing))); + } + public static MvcHtmlString ImageActionLink(this HtmlHelper helper, string imageUrl, object imgAttributes, string actionName, object routeValues, object htmlAttributes) { return ImageActionLink(helper, imageUrl, imgAttributes, actionName, null, routeValues, htmlAttributes); diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 776a3069d..c45f5c4cb 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -348,6 +348,8 @@ + + diff --git a/NzbDrone.Web/Scripts/NzbDrone/AutoBind.js b/NzbDrone.Web/Scripts/NzbDrone/AutoBind.js index a8eb52972..1e8026218 100644 --- a/NzbDrone.Web/Scripts/NzbDrone/AutoBind.js +++ b/NzbDrone.Web/Scripts/NzbDrone/AutoBind.js @@ -42,21 +42,4 @@ } }); }); -}); - -//Make .ajaxLink use jQuery Ajax for the request - -$(document).on('click', '.ajaxLink', function (event) { - event.preventDefault(); - var onSuccess = $(this).attr('onsuccess'); - $.ajax({ - url: this.href, - cache: false, - success: function () { - if (onSuccess) { - window[onSuccess](); - } - } - }); - return false; }); \ No newline at end of file diff --git a/NzbDrone.Web/Scripts/NzbDrone/grid.js b/NzbDrone.Web/Scripts/NzbDrone/grid.js index 7095a0f28..4c3c8eed0 100644 --- a/NzbDrone.Web/Scripts/NzbDrone/grid.js +++ b/NzbDrone.Web/Scripts/NzbDrone/grid.js @@ -1,6 +1,6 @@ /* Click on row, show details */ $(document).on('click', '.seriesTable a, .dataTable a', function (event) { - if ($(this).hasClass('ajaxLink') || $(this).attr('onclick')) + if ($(this).attr('data-ajax') === "true") return; event.preventDefault(); @@ -46,14 +46,6 @@ function fnFormatDetails(nTr) { return aData["Details"]; } -//Create Image -function createImageAjaxLink(url, image, alt, title, classes) { - var html = '' + - '' + alt + ''; - - return html; -} - //Reload/Redraw the grid from the server (bServerSide == true) function redrawGrid() { oTable.fnDraw(); diff --git a/NzbDrone.Web/Scripts/jquery.unobtrusive-ajax.js b/NzbDrone.Web/Scripts/jquery.unobtrusive-ajax.js new file mode 100644 index 000000000..eecd7c91c --- /dev/null +++ b/NzbDrone.Web/Scripts/jquery.unobtrusive-ajax.js @@ -0,0 +1,163 @@ +/*! +** Unobtrusive Ajax support library for jQuery +** Copyright (C) Microsoft Corporation. All rights reserved. +*/ + +/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ +/*global window: false, jQuery: false */ + +(function ($) { + var data_click = "unobtrusiveAjaxClick", + data_validation = "unobtrusiveValidation"; + + function getFunction(code, argNames) { + var fn = window, parts = (code || "").split("."); + while (fn && parts.length) { + fn = fn[parts.shift()]; + } + if (typeof (fn) === "function") { + return fn; + } + argNames.push(code); + return Function.constructor.apply(null, argNames); + } + + function isMethodProxySafe(method) { + return method === "GET" || method === "POST"; + } + + function asyncOnBeforeSend(xhr, method) { + if (!isMethodProxySafe(method)) { + xhr.setRequestHeader("X-HTTP-Method-Override", method); + } + } + + function asyncOnSuccess(element, data, contentType) { + var mode; + + if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us + return; + } + + mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase(); + $(element.getAttribute("data-ajax-update")).each(function (i, update) { + var top; + + switch (mode) { + case "BEFORE": + top = update.firstChild; + $("
").html(data).contents().each(function () { + update.insertBefore(this, top); + }); + break; + case "AFTER": + $("
").html(data).contents().each(function () { + update.appendChild(this); + }); + break; + default: + $(update).html(data); + break; + } + }); + } + + function asyncRequest(element, options) { + var confirm, loading, method, duration; + + confirm = element.getAttribute("data-ajax-confirm"); + if (confirm && !window.confirm(confirm)) { + return; + } + + loading = $(element.getAttribute("data-ajax-loading")); + duration = element.getAttribute("data-ajax-loading-duration") || 0; + + $.extend(options, { + type: element.getAttribute("data-ajax-method") || undefined, + url: element.getAttribute("data-ajax-url") || undefined, + beforeSend: function (xhr) { + var result; + asyncOnBeforeSend(xhr, method); + result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments); + if (result !== false) { + loading.show(duration); + } + return result; + }, + complete: function () { + loading.hide(duration); + getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments); + }, + success: function (data, status, xhr) { + asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html"); + getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments); + }, + error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]) + }); + + options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" }); + + method = options.type.toUpperCase(); + if (!isMethodProxySafe(method)) { + options.type = "POST"; + options.data.push({ name: "X-HTTP-Method-Override", value: method }); + } + + $.ajax(options); + } + + function validate(form) { + var validationInfo = $(form).data(data_validation); + return !validationInfo || !validationInfo.validate || validationInfo.validate(); + } + + $("a[data-ajax=true]").live("click", function (evt) { + evt.preventDefault(); + asyncRequest(this, { + url: this.href, + type: "GET", + data: [] + }); + }); + + $("form[data-ajax=true] input[type=image]").live("click", function (evt) { + var name = evt.target.name, + $target = $(evt.target), + form = $target.parents("form")[0], + offset = $target.offset(); + + $(form).data(data_click, [ + { name: name + ".x", value: Math.round(evt.pageX - offset.left) }, + { name: name + ".y", value: Math.round(evt.pageY - offset.top) } + ]); + + setTimeout(function () { + $(form).removeData(data_click); + }, 0); + }); + + $("form[data-ajax=true] :submit").live("click", function (evt) { + var name = evt.target.name, + form = $(evt.target).parents("form")[0]; + + $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []); + + setTimeout(function () { + $(form).removeData(data_click); + }, 0); + }); + + $("form[data-ajax=true]").live("submit", function (evt) { + var clickInfo = $(this).data(data_click) || []; + evt.preventDefault(); + if (!validate(this)) { + return; + } + asyncRequest(this, { + url: this.action, + type: this.method || "GET", + data: clickInfo.concat($(this).serializeArray()) + }); + }); +}(jQuery)); \ No newline at end of file diff --git a/NzbDrone.Web/Scripts/jquery.unobtrusive-ajax.min.js b/NzbDrone.Web/Scripts/jquery.unobtrusive-ajax.min.js new file mode 100644 index 000000000..3542991c1 --- /dev/null +++ b/NzbDrone.Web/Scripts/jquery.unobtrusive-ajax.min.js @@ -0,0 +1,5 @@ +/* +** Unobtrusive Ajax support library for jQuery +** Copyright (C) Microsoft Corporation. All rights reserved. +*/ +(function(a){var b="unobtrusiveAjaxClick",g="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function d(a){return a==="GET"||a==="POST"}function f(b,a){!d(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function h(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(f,c){var e;switch(d){case"BEFORE":e=c.firstChild;a("
").html(b).contents().each(function(){c.insertBefore(this,e)});break;case"AFTER":a("
").html(b).contents().each(function(){c.appendChild(this)});break;default:a(c).html(b)}})}function e(b,e){var j,k,g,i;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));i=b.getAttribute("data-ajax-loading-duration")||0;a.extend(e,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,beforeSend:function(d){var a;f(d,g);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(this,arguments);a!==false&&k.show(i);return a},complete:function(){k.hide(i);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(this,arguments)},success:function(a,e,d){h(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(this,arguments)},error:c(b.getAttribute("data-ajax-failure"),["xhr","status","error"])});e.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});g=e.type.toUpperCase();if(!d(g)){e.type="POST";e.data.push({name:"X-HTTP-Method-Override",value:g})}a.ajax(e)}function i(c){var b=a(c).data(g);return!b||!b.validate||b.validate()}a("a[data-ajax=true]").live("click",function(a){a.preventDefault();e(this,{url:this.href,type:"GET",data:[]})});a("form[data-ajax=true] input[type=image]").live("click",function(c){var g=c.target.name,d=a(c.target),f=d.parents("form")[0],e=d.offset();a(f).data(b,[{name:g+".x",value:Math.round(c.pageX-e.left)},{name:g+".y",value:Math.round(c.pageY-e.top)}]);setTimeout(function(){a(f).removeData(b)},0)});a("form[data-ajax=true] :submit").live("click",function(c){var e=c.target.name,d=a(c.target).parents("form")[0];a(d).data(b,e?[{name:e,value:c.target.value}]:[]);setTimeout(function(){a(d).removeData(b)},0)});a("form[data-ajax=true]").live("submit",function(d){var c=a(this).data(b)||[];d.preventDefault();if(!i(this))return;e(this,{url:this.action,type:this.method||"GET",data:c.concat(a(this).serializeArray())})})})(jQuery); \ No newline at end of file diff --git a/NzbDrone.Web/Views/History/Index.cshtml b/NzbDrone.Web/Views/History/Index.cshtml index 73cbde43c..b66bbd996 100644 --- a/NzbDrone.Web/Views/History/Index.cshtml +++ b/NzbDrone.Web/Views/History/Index.cshtml @@ -3,8 +3,8 @@ @{ViewBag.Title = "History";} @section ActionMenu{ } @section HeaderContent diff --git a/NzbDrone.Web/Views/Log/Index.cshtml b/NzbDrone.Web/Views/Log/Index.cshtml index 0f0ec7d2a..7fbd1f10c 100644 --- a/NzbDrone.Web/Views/Log/Index.cshtml +++ b/NzbDrone.Web/Views/Log/Index.cshtml @@ -3,7 +3,7 @@ @{ ViewBag.Title = "Logs";} @section ActionMenu{ } diff --git a/NzbDrone.Web/Views/Missing/Index.cshtml b/NzbDrone.Web/Views/Missing/Index.cshtml index d819df6b5..2cb3ca1e4 100644 --- a/NzbDrone.Web/Views/Missing/Index.cshtml +++ b/NzbDrone.Web/Views/Missing/Index.cshtml @@ -9,9 +9,9 @@ } @section ActionMenu{ }
@@ -81,7 +81,9 @@ } }, //Grabbed On { sWidth: '40px', "mDataProp": "EpisodeId", "bSortable": false, "fnRender": function (row) { - return createImageAjaxLink('/Episode/Search?episodeId=' + row.aData["EpisodeId"], '../../Content/Images/Search.png', 'Search', 'Search for Episode', 'gridAction'); + var link = '@Ajax.ImageActionLink("../../Content/Images/Search.png", new { title = "Search for Episode", alt = "Search", @class = "gridAction" }, "Search", "Episode", new { episodeId = "REPLACE" }, null, null)'; + link = link.replace("REPLACE", row.aData["EpisodeId"]); + return link; } }, //Actions { sWidth: 'auto', "mDataProp": "Details", "bSortable": false, "bVisible": false, "fnRender": function (row) { diff --git a/NzbDrone.Web/Views/Series/Details.cshtml b/NzbDrone.Web/Views/Series/Details.cshtml index 9f3d80af0..39eaf8e1d 100644 --- a/NzbDrone.Web/Views/Series/Details.cshtml +++ b/NzbDrone.Web/Views/Series/Details.cshtml @@ -68,9 +68,9 @@ { } diff --git a/NzbDrone.Web/Views/Series/Episode.cshtml b/NzbDrone.Web/Views/Series/Episode.cshtml index e2bffc20a..e9b5c9e32 100644 --- a/NzbDrone.Web/Views/Series/Episode.cshtml +++ b/NzbDrone.Web/Views/Series/Episode.cshtml @@ -25,7 +25,7 @@ @*Commands Column*@ - @Html.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridAction" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, new { @class = "ajaxLink" }) + @Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridAction" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, null, null) @Model.Status diff --git a/NzbDrone.Web/Views/Series/Index.cshtml b/NzbDrone.Web/Views/Series/Index.cshtml index 6e1db83ab..9a21d2a32 100644 --- a/NzbDrone.Web/Views/Series/Index.cshtml +++ b/NzbDrone.Web/Views/Series/Index.cshtml @@ -75,7 +75,7 @@ @section ActionMenu{ } diff --git a/NzbDrone.Web/Views/Series/Season.cshtml b/NzbDrone.Web/Views/Series/Season.cshtml index a7db36a74..5764cffd8 100644 --- a/NzbDrone.Web/Views/Series/Season.cshtml +++ b/NzbDrone.Web/Views/Series/Season.cshtml @@ -23,8 +23,8 @@ @*Commands Column*@ - @Html.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for all episodes in this season", @class = "gridAction" }, "SearchSeason", "Episode", new { SeriesId = Model.SeriesId, SeasonNumber = Model.SeasonNumber }, new { @class = "ajaxLink" }) - @Html.ImageActionLink("../../Content/Images/Rename.png", new { Alt = "Rename", Title = "Rename all episodes in this season", @class = "gridAction" }, "RenameSeason", "Episode", new { SeriesId = Model.SeriesId, SeasonNumber = Model.SeasonNumber }, new { @class = "ajaxLink" }) + @Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for all episodes in this season", @class = "gridAction" }, "SearchSeason", "Episode", new { SeriesId = Model.SeriesId, SeasonNumber = Model.SeasonNumber }, null, null) + @Ajax.ImageActionLink("../../Content/Images/Rename.png", new { Alt = "Rename", Title = "Rename all episodes in this season", @class = "gridAction" }, "RenameSeason", "Episode", new { SeriesId = Model.SeriesId, SeasonNumber = Model.SeasonNumber }, null, null) diff --git a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml index 14c3123e7..e9be7ca5b 100644 --- a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml +++ b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml @@ -29,6 +29,7 @@ @Html.IncludeScript("jquery.signalR.min.js") @Html.IncludeScript("jquery.validate.js") @Html.IncludeScript("jquery.validate.unobtrusive.js") + @Html.IncludeScript("jquery.unobtrusive-ajax.min.js") @Html.IncludeScript("jquery.cookie.js") @Html.IncludeScript("doTimeout.js") @Html.IncludeScript("conditional-validation.js") diff --git a/NzbDrone.Web/Views/System/Jobs.cshtml b/NzbDrone.Web/Views/System/Jobs.cshtml index 463b7030d..35e87567c 100644 --- a/NzbDrone.Web/Views/System/Jobs.cshtml +++ b/NzbDrone.Web/Views/System/Jobs.cshtml @@ -70,12 +70,13 @@ { sWidth: '150px', "mDataProp": "LastExecution" }, //LastExecution { sWidth: '80px', "mDataProp": "Success" }, //Success { sWidth: '40px', "mDataProp": "Actions", "bSortable": false, "fnRender": function (row) { - if (!row.aData["Enable"]) - return ""; + if (!row.aData["Enable"]) + return ""; - return createImageAjaxLink('/System/RunJob?typeName=' + row.aData["TypeName"], '../../Content/Images/Gear.png', 'Run', 'Run Job', 'gridAction'); - //return createImageAjaxLink('/History/Delete?historyId=' + row.aData["HistoryId"], '../../Content/Images/X.png', 'Delete', 'Delete from History', 'searchImage'); - } + var link = '@Ajax.ImageActionLink("../../Content/Images/Gear.png", new { title = "Run Job", alt = "Job", @class = "gridAction" }, "RunJob", "System", new { typeName = "REPLACE" }, null, null)'; + link = link.replace("REPLACE", row.aData["TypeName"]); + return link; + } } //Actions ], "aaSorting": [[4, 'asc']] diff --git a/NzbDrone.Web/Views/Upcoming/Index.cshtml b/NzbDrone.Web/Views/Upcoming/Index.cshtml index 663c87392..6731d689d 100644 --- a/NzbDrone.Web/Views/Upcoming/Index.cshtml +++ b/NzbDrone.Web/Views/Upcoming/Index.cshtml @@ -20,7 +20,7 @@ } @section ActionMenu{ }
diff --git a/NzbDrone.Web/Views/Upcoming/UpcomingEpisode.cshtml b/NzbDrone.Web/Views/Upcoming/UpcomingEpisode.cshtml index cce7bfdfc..8ab45ff19 100644 --- a/NzbDrone.Web/Views/Upcoming/UpcomingEpisode.cshtml +++ b/NzbDrone.Web/Views/Upcoming/UpcomingEpisode.cshtml @@ -36,7 +36,7 @@ @*Commands Column*@ @Model.Status - @Html.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridAction" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, new { @class = "ajaxLink" }) + @Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridAction" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, null, null) diff --git a/NzbDrone.Web/Views/Update/Index.cshtml b/NzbDrone.Web/Views/Update/Index.cshtml index 842ba0e89..20e6cea24 100644 --- a/NzbDrone.Web/Views/Update/Index.cshtml +++ b/NzbDrone.Web/Views/Update/Index.cshtml @@ -9,7 +9,7 @@ else {

Available Update: @Model.UpdatePackage.Version - @Html.ActionLink("Update", "StartUpdate", "Update", null, new { @class = "ajaxLink" }) + @Ajax.ActionLink("Update", "StartUpdate", "Update", null)

} @if (Model.LogFiles.Count != 0) diff --git a/NzbDrone.Web/packages.config b/NzbDrone.Web/packages.config index 4c065e51e..e93e28704 100644 --- a/NzbDrone.Web/packages.config +++ b/NzbDrone.Web/packages.config @@ -5,6 +5,7 @@ + diff --git a/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/Content/Scripts/jquery.unobtrusive-ajax.js b/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/Content/Scripts/jquery.unobtrusive-ajax.js new file mode 100644 index 000000000..eecd7c91c --- /dev/null +++ b/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/Content/Scripts/jquery.unobtrusive-ajax.js @@ -0,0 +1,163 @@ +/*! +** Unobtrusive Ajax support library for jQuery +** Copyright (C) Microsoft Corporation. All rights reserved. +*/ + +/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ +/*global window: false, jQuery: false */ + +(function ($) { + var data_click = "unobtrusiveAjaxClick", + data_validation = "unobtrusiveValidation"; + + function getFunction(code, argNames) { + var fn = window, parts = (code || "").split("."); + while (fn && parts.length) { + fn = fn[parts.shift()]; + } + if (typeof (fn) === "function") { + return fn; + } + argNames.push(code); + return Function.constructor.apply(null, argNames); + } + + function isMethodProxySafe(method) { + return method === "GET" || method === "POST"; + } + + function asyncOnBeforeSend(xhr, method) { + if (!isMethodProxySafe(method)) { + xhr.setRequestHeader("X-HTTP-Method-Override", method); + } + } + + function asyncOnSuccess(element, data, contentType) { + var mode; + + if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us + return; + } + + mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase(); + $(element.getAttribute("data-ajax-update")).each(function (i, update) { + var top; + + switch (mode) { + case "BEFORE": + top = update.firstChild; + $("
").html(data).contents().each(function () { + update.insertBefore(this, top); + }); + break; + case "AFTER": + $("
").html(data).contents().each(function () { + update.appendChild(this); + }); + break; + default: + $(update).html(data); + break; + } + }); + } + + function asyncRequest(element, options) { + var confirm, loading, method, duration; + + confirm = element.getAttribute("data-ajax-confirm"); + if (confirm && !window.confirm(confirm)) { + return; + } + + loading = $(element.getAttribute("data-ajax-loading")); + duration = element.getAttribute("data-ajax-loading-duration") || 0; + + $.extend(options, { + type: element.getAttribute("data-ajax-method") || undefined, + url: element.getAttribute("data-ajax-url") || undefined, + beforeSend: function (xhr) { + var result; + asyncOnBeforeSend(xhr, method); + result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments); + if (result !== false) { + loading.show(duration); + } + return result; + }, + complete: function () { + loading.hide(duration); + getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments); + }, + success: function (data, status, xhr) { + asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html"); + getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments); + }, + error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]) + }); + + options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" }); + + method = options.type.toUpperCase(); + if (!isMethodProxySafe(method)) { + options.type = "POST"; + options.data.push({ name: "X-HTTP-Method-Override", value: method }); + } + + $.ajax(options); + } + + function validate(form) { + var validationInfo = $(form).data(data_validation); + return !validationInfo || !validationInfo.validate || validationInfo.validate(); + } + + $("a[data-ajax=true]").live("click", function (evt) { + evt.preventDefault(); + asyncRequest(this, { + url: this.href, + type: "GET", + data: [] + }); + }); + + $("form[data-ajax=true] input[type=image]").live("click", function (evt) { + var name = evt.target.name, + $target = $(evt.target), + form = $target.parents("form")[0], + offset = $target.offset(); + + $(form).data(data_click, [ + { name: name + ".x", value: Math.round(evt.pageX - offset.left) }, + { name: name + ".y", value: Math.round(evt.pageY - offset.top) } + ]); + + setTimeout(function () { + $(form).removeData(data_click); + }, 0); + }); + + $("form[data-ajax=true] :submit").live("click", function (evt) { + var name = evt.target.name, + form = $(evt.target).parents("form")[0]; + + $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []); + + setTimeout(function () { + $(form).removeData(data_click); + }, 0); + }); + + $("form[data-ajax=true]").live("submit", function (evt) { + var clickInfo = $(this).data(data_click) || []; + evt.preventDefault(); + if (!validate(this)) { + return; + } + asyncRequest(this, { + url: this.action, + type: this.method || "GET", + data: clickInfo.concat($(this).serializeArray()) + }); + }); +}(jQuery)); \ No newline at end of file diff --git a/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/Content/Scripts/jquery.unobtrusive-ajax.min.js b/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/Content/Scripts/jquery.unobtrusive-ajax.min.js new file mode 100644 index 000000000..3542991c1 --- /dev/null +++ b/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/Content/Scripts/jquery.unobtrusive-ajax.min.js @@ -0,0 +1,5 @@ +/* +** Unobtrusive Ajax support library for jQuery +** Copyright (C) Microsoft Corporation. All rights reserved. +*/ +(function(a){var b="unobtrusiveAjaxClick",g="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function d(a){return a==="GET"||a==="POST"}function f(b,a){!d(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function h(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(f,c){var e;switch(d){case"BEFORE":e=c.firstChild;a("
").html(b).contents().each(function(){c.insertBefore(this,e)});break;case"AFTER":a("
").html(b).contents().each(function(){c.appendChild(this)});break;default:a(c).html(b)}})}function e(b,e){var j,k,g,i;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));i=b.getAttribute("data-ajax-loading-duration")||0;a.extend(e,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,beforeSend:function(d){var a;f(d,g);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(this,arguments);a!==false&&k.show(i);return a},complete:function(){k.hide(i);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(this,arguments)},success:function(a,e,d){h(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(this,arguments)},error:c(b.getAttribute("data-ajax-failure"),["xhr","status","error"])});e.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});g=e.type.toUpperCase();if(!d(g)){e.type="POST";e.data.push({name:"X-HTTP-Method-Override",value:g})}a.ajax(e)}function i(c){var b=a(c).data(g);return!b||!b.validate||b.validate()}a("a[data-ajax=true]").live("click",function(a){a.preventDefault();e(this,{url:this.href,type:"GET",data:[]})});a("form[data-ajax=true] input[type=image]").live("click",function(c){var g=c.target.name,d=a(c.target),f=d.parents("form")[0],e=d.offset();a(f).data(b,[{name:g+".x",value:Math.round(c.pageX-e.left)},{name:g+".y",value:Math.round(c.pageY-e.top)}]);setTimeout(function(){a(f).removeData(b)},0)});a("form[data-ajax=true] :submit").live("click",function(c){var e=c.target.name,d=a(c.target).parents("form")[0];a(d).data(b,e?[{name:e,value:c.target.value}]:[]);setTimeout(function(){a(d).removeData(b)},0)});a("form[data-ajax=true]").live("submit",function(d){var c=a(this).data(b)||[];d.preventDefault();if(!i(this))return;e(this,{url:this.action,type:this.method||"GET",data:c.concat(a(this).serializeArray())})})})(jQuery); \ No newline at end of file diff --git a/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/jQuery.Ajax.Unobtrusive.2.0.20126.16343.nupkg b/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/jQuery.Ajax.Unobtrusive.2.0.20126.16343.nupkg new file mode 100644 index 000000000..e699dfe4f Binary files /dev/null and b/packages/jQuery.Ajax.Unobtrusive.2.0.20126.16343/jQuery.Ajax.Unobtrusive.2.0.20126.16343.nupkg differ