Вам повезло, я сделал это!
Итак, первое, что вам нужно, это новый ViewEngine для обработки рендеринга страницы без всего того, что обычно мешает вашим модальным окнам. Самый простой способ сделать это - использовать в основном пустую главную страницу для ваших модальных окон. Вы хотите, чтобы логика переключения главной страницы была в стороне и в пользовательском ViewEngine, потому что в противном случае каждый метод контроллера должен иметь if () else () повсеместно, обнаруживающий IsAjaxRequest (). Мне нравится сухой, Сахара сухой.
С помощью этой техники у меня также есть преимущество в том, что я очень изящно деградирую. Мой сайт работает без JavaScript просто отлично. Ссылки в порядке, формы работают, ноль изменений кода для перехода от "модального сайта" к отправке простой старой HTML-формы.
Все, что я сделал, это создал подкласс движка по умолчанию и добавил несколько битов выбора MasterPage:
The View Engine:
public class ModalViewEngine : VirtualPathProviderViewEngine
{
public ModalViewEngine()
{
/* {0} = view name or master page name
* {1} = controller name */
MasterLocationFormats = new[] {
"~/Views/Shared/{0}.master"
};
ViewLocationFormats = new[] {
"~/Views/{1}/{0}.aspx",
"~/Views/Shared/{0}.aspx"
};
PartialViewLocationFormats = new[] {
"~/Views/{1}/{0}.ascx",
};
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
throw new NotImplementedException();
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
return new WebFormView(viewPath, masterPath );
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
//you might have to customize this bit
if (controllerContext.HttpContext.Request.IsAjaxRequest())
return base.FindView(controllerContext, viewName, "Modal", useCache);
return base.FindView(controllerContext, viewName, "Site", useCache);
}
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
return base.FileExists(controllerContext, virtualPath);
}
}
Так что моя страница Modal.Master очень проста. Все, что у меня есть, это div-обертка, поэтому я знаю, когда что-то отображается внутри модального окна. Это будет полезно, когда вам нужно выбрать определенные элементы с помощью jquery только тогда, когда они находятся в «модальном режиме».
Modal.Master
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<div id="modalcontent"><asp:ContentPlaceHolder ID="MainContent" runat="server" /></div>
Следующим шагом будет создание вашей формы. Я использую имя свойства по умолчанию = входное имя, чтобы легко связать модель и упростить процесс. Ничего особенного в форме. Я выгляжу так же, как вы бы сделали это нормально. (Обратите внимание, что я использую MVC 2 и EditorFor () в своем коде, но это не должно иметь значения) Вот мой последний HTML:
Вывод HTML
<div id="modalcontent">
<h2>EditFood</h2>
<div id="form">
<form method="post" action="/edit/food?Length=8">
<input id="CommonName" class="text-box single-line" type="text" value="" name="CommonName"/>
<input class="button" type="submit" value="Edit Food"/>
</form>
</div>
</div>
Помимо очень приятного связывания моделей, вы также можете использовать плагин Jquery.Form , чтобы иметь простые и понятные возможности ajax в вашем приложении с минимальным кодом. Теперь я выбрал ColorBox в качестве скрипта модального окна исключительно потому, что мне нужны прозрачные углы Facebookesque, и мне нравятся точки расширяемости, добавленные автором.
Теперь, когда эти сценарии объединены, вы получите действительно хорошую комбинацию, которая делает эту технику по-настоящему глупой в javascript. Единственный javascript, который я должен был добавить, был (внутри document.ready):
Javascript / Jquery
$("a.edit").colorbox({ maxWidth: "800px", opacity: 0.4, initialWidth: 50, initialHeight: 50 });
$().bind('cbox_complete', function () {
$("#form form").ajaxForm(function () { $.fn.colorbox.close() });
});
Здесь я говорю ColorBox, чтобы открыть модальное окно для моих ссылок редактирования (Edit Food). Затем с привязкой перейдите к событию complete из colorbox, чтобы соединить ваши элементы ajaxform с обратным вызовом успеха, чтобы сообщить ColorBox закрыть модальное окно. Вот и все.
Этот код был сделан как доказательство концепции, и поэтому движок представления действительно облегчен, и нет проверки или другой стандартной формы. ColorBox и JQuery.Form имеют тонну поддержки расширяемости, поэтому их легко настроить.
Обратите внимание, что все это было сделано в MVC 2, но в любом случае, вот мой код контроллера, просто чтобы показать, как легко это сделать. Помните, моя цель концепции была в том, чтобы заставить модальные окна работать таким образом, чтобы мне не нужно было вносить какие-либо изменения в коде, кроме настройки какой-то базовой инфраструктуры.
[UrlRoute(Path="edit/food")]
public ActionResult EditFood()
{
return View(new Food());
}
[HttpPost][UrlRoute(Path = "edit/food")]
public ActionResult EditFood(Food food)
{
return View(food);
}