Модальное окно bootstrap для редактирования форм

от автора

Возникла необходимость использовать плагин bootstrap-modal.js для редактирования формы. Казалось бы тривиальная задача, но пришлось столкнуться с некоторыми сложностями. В данной статье поделюсь с вами своим решением, более изящные решения и здоровая критика приветствуются.

Имеется страница с формой для редактирования товара. Добавим на форму выпадающий список с перечнем производителей. Рядом разместим бутстраповскую иконку icon-plus-sing, которая и будет триггером для вызова модального окна.

image

<div id="edit_producer" class="modal fade hide in"> </div>  <div class="editor-label">     @Html.LabelFor(model => model.Producers) </div> <div class="editor-field">     @Html.DropDownListFor(model => model.ProducerId, Model.Producers)     @Ajax.RawActionLink(                         "<i class='icon-plus-sign icon-2x'></i>",                         ActionConstants.Edit,                         ProducerController.Name,                         null,                         new AjaxOptions                             {                                 UpdateTargetId = "edit_producer",                                 InsertionMode = InsertionMode.Replace,                                 HttpMethod = "GET",                                 OnSuccess = "ShowProducerEditModal"                             },                         null)      @Html.ValidationMessageFor(model => model.Producers) </div> </div> 

Примечание: используются кастомные html-хелперы DropDownListFor и RawActionLink.

Идем дальше. Пишем js обработчик на событие OnSuccess.

function ShowProducerEditModal() {      $('#edit_producer').modal('show');  } 

Далее нам нужен экшен в контроллере ProducerController для рендеринга содержимого модального окна.

[HttpGet] public ActionResult Edit(long? id) {     ProducerEditModel model = service.GetProducerEditModel(id);     return PartialView("ProducerEditPartial", model); } 

Частичное предстваление контента модального окна:

@using (Ajax.BeginForm(                 ActionConstants.Edit,                 ProducerController.Name,                 new AjaxOptions                     {                         HttpMethod = "POST",                         OnSuccess = "OnSuccess"                     })) {     <div class="modal-header">         <a class="close" data-dismiss="modal">×</a>         <h3>Редактирование производителя</h3>     </div>     <div class="modal-body">         @Html.HiddenFor(model => model.Id)          <div class="editor-label">             @Html.LabelFor(model => model.Name)         </div>         <div class="editor-field">             @Html.EditorFor(model => model.Name)             @Html.ValidationMessageFor(model => model.Name)         </div>     </div>     <div class="modal-footer">         <input type="submit" class="btn btn-success" value="Сохранить" />         <a href="#" class="btn" data-dismiss="modal">Close</a>     </div> } 

В результате получаем красивый попап с формой по клику на триггер.
image

Следом стоит задача валидации редактируемой формы и добавление нового элемента в выпадающий список. Для этого пишем обработчик события OnSuccess. Предусмотрим возможность добавления и редактирования элемента выпадающего списка. Если содержимое формы оказывается не валидным, то отрисовываем форму внутри модального окна ещё раз.

function OnSuccess(data) {     if (data.isValid) {         $('#edit_producer').modal('hide');         if (data.isNew) {             AppendToDropDownList(data.name, data.id, 'ProducerId');         } else {             EditDropDownListItem(data.name, data.id, 'ProducerId');         }     } else {         $('#edit_producer').html(data.partialView);     } }  function AppendToDropDownList(text, value, ddlId) {     var newItem = $('<option/>', {         value: value,         text: text     });      $('#' + ddlId).append(newItem); }  function EditDropDownListItem(text, value, ddlId) {     $('#' + ddlId + ' option[value="' + value + '"]').text(text).val(value); } 

В контроллер ProducerController пишем ещё один экшен.
Примечание: используется кастомный статический метод RenderRazorViewToString

[HttpPost] public ActionResult Edit(ProducerEditModel model) {     if (ModelState.IsValid)     {         bool isNew = model.Id == 0;         long id = service.Save(model);         return Json(new             {                 isValid = true,                 id = id,                 name = model.Name,                 isNew = isNew             });     }      return Json(new     {         partialView = RenderUtils.RenderRazorViewToString(this, "ProducerEditPartial", model),         isValid = false     }); } 

image

В общем-то на этом все. Спасибо за внимание.

Полезные ссылки:
Русскоязычное руководство по bootstrap
Туториал по bootstrap-modal.js
Исходники bootstrap-modal.js

ссылка на оригинал статьи http://habrahabr.ru/post/179211/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *