MVC 4 부트스트랩을 사용한 모달폼 편집
인트라넷 웹 애플리케이션을 개발하기 위해 MVC 4와 엔티티 프레임워크를 사용하고 있습니다.편집 작업으로 수정할 수 있는 사용자 목록이 있습니다.모달 폼을 사용하여 앱을 좀 더 역동적으로 만들고 싶었습니다.그래서 편집 뷰를 부트스트랩모달에 넣으려고 했는데 2가지 질문이 있습니다.
- 단순 뷰를 사용할까요, 아니면 부분 뷰를 사용할까요?
- 검증을 실행하는 방법(실제로 동작하지만 원래 보기로 리다이렉트되므로 모달 형식이 아님)
AJAX 및/또는 jQuery를 사용해야 한다고 생각합니다만, 이러한 테크놀로지는 처음입니다.어떤 도움이라도 주시면 감사하겠습니다.
편집: 내 인덱스 보기:
@model IEnumerable<BuSIMaterial.Models.Person>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<br />
<div class="group">
<input type="button" value="New person" class="btn" onclick="location.href='@Url.Action("Create")';return false;"/>
<input type="button" value="Download report" class="btn" onclick="location.href='@Url.Action("PersonReport")';return false;"/>
</div>
@using (Html.BeginForm("SelectedPersonDetails", "Person"))
{
<form class="form-search">
<input type="text" id="tbPerson" name="tbPerson" placeholder="Find an employee..." class="input-medium search-query">
<button type="submit" class="btn">Search</button>
</form>
}
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Start Date</th>
<th>End Date</th>
<th>Details</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (BuSIMaterial.Models.Person item in ViewBag.PageOfPersons)
{
<tr>
<td>@item.FirstName</td>
<td>@item.LastName</td>
<td>@item.StartDate.ToShortDateString()</td>
<td>
@if (item.EndDate.HasValue)
{
@item.EndDate.Value.ToShortDateString()
}
</td>
<td>
<a class="details_link" data-target-id="@item.Id_Person">Details</a>
</td>
<td>
<div>
<button class="btn btn-primary edit-person" data-id="@item.Id_Person">Edit</button>
</div>
</td>
</tr>
<tr>
<td colspan="6">
<table>
<tr>
<th>National Number</th>
<td>@item.NumNat</td>
</tr>
<tr>
<th>Vehicle Category</th>
<td>@item.ProductPackageCategory.Name</td>
</tr>
<tr>
<th>Upgrade</th><td>@item.Upgrade</td>
</tr>
<tr>
<th>House to work</th>
<td>@item.HouseToWorkKilometers.ToString("G29")</td>
</tr>
</table>
<div id="details_@item.Id_Person"></div>
</td>
</tr>
}
</tbody>
</table>
<div class="modal hide fade in" id="edit-member">
<div id="edit-person-container"></div>
</div>
@section Scripts
{
@Scripts.Render("~/bundles/jqueryui")
@Styles.Render("~/Content/themes/base/css")
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$('#tbPerson').autocomplete({
source: '@Url.Action("AutoComplete")'
});
$(".details_link").click(function () {
var id = $(this).data("target-id");
var url = '/ProductAllocation/ListByOwner/' + id;
$("#details_"+ id).load(url);
});
$('.edit-person').click(function () {
var url = "/Person/EditPerson";
var id = $(this).attr('data-id');
$.get(url + '/' + id, function (data) {
$('#edit-person-container').html(data);
$('.edit-person').modal('show');
});
});
});
</script>
}
내 부분 보기:
@model BuSIMaterial.Models.Person
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Edit</h3>
</div>
<div>
@using (Ajax.BeginForm("EditPerson", "Person", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "list-of-people"
}))
{
@Html.ValidationSummary()
@Html.AntiForgeryToken()
<div class="modal-body">
<div class="editor-field">
@Html.TextBoxFor(model => model.FirstName, new { maxlength = 50 })
@Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.LastName, new { maxlength = 50 })
@Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<div class="modal-footer">
<button class="btn btn-inverse" type="submit">Save</button>
</div>
}
부분 보기를 사용해야 합니다.다음과 같은 접근방식을 사용합니다.
뷰 모델을 사용하여 도메인 모델을 뷰에 넘기지 않도록 합니다.
public class EditPersonViewModel
{
public int Id { get; set; } // this is only used to retrieve record from Db
public string Name { get; set; }
public string Age { get; set; }
}
고객님의 고객명PersonController:
[HttpGet] // this action result returns the partial containing the modal
public ActionResult EditPerson(int id)
{
var viewModel = new EditPersonViewModel();
viewModel.Id = id;
return PartialView("_EditPersonPartial", viewModel);
}
[HttpPost] // this action takes the viewModel from the modal
public ActionResult EditPerson(EditPersonViewModel viewModel)
{
if (ModelState.IsValid)
{
var toUpdate = personRepo.Find(viewModel.Id);
toUpdate.Name = viewModel.Name;
toUpdate.Age = viewModel.Age;
personRepo.InsertOrUpdate(toUpdate);
personRepo.Save();
return View("Index");
}
}
에 '보다 낫다'라는 보세요._EditPersonPartial모달 헤더, 본문 및 바닥글을 포함합니다.아약스그것은 강한 활자로 되어 있고 우리의 뷰 모델을 받아들입니다.
@model Namespace.ViewModels.EditPersonViewModel
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Edit group member</h3>
</div>
<div>
@using (Ajax.BeginForm("EditPerson", "Person", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "list-of-people"
}))
{
@Html.ValidationSummary()
@Html.AntiForgeryToken()
<div class="modal-body">
@Html.Bootstrap().ControlGroup().TextBoxFor(x => x.Name)
@Html.Bootstrap().ControlGroup().TextBoxFor(x => x.Age)
</div>
<div class="modal-footer">
<button class="btn btn-inverse" type="submit">Save</button>
</div>
}
다음으로 어플리케이션의 어딘가에 다른 부분 _peoplePartial.cshtml 등을 입력합니다.
<div>
@foreach(var person in Model.People)
{
<button class="btn btn-primary edit-person" data-id="@person.PersonId">Edit</button>
}
</div>
// this is the modal definition
<div class="modal hide fade in" id="edit-person">
<div id="edit-person-container"></div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('.edit-person').click(function () {
var url = "/Person/EditPerson"; // the url to the controller
var id = $(this).attr('data-id'); // the id that's given to each button in the list
$.get(url + '/' + id, function (data) {
$('#edit-person-container').html(data);
$('#edit-person').modal('show');
});
});
});
</script>
나는 그것을 사용하는 것을 피하는 것을 선호한다.Ajax.BeginFormJQuery 아약스내 경험으로는 이렇게 쓰여진 코드를 유지하는 것이 더 쉽다.자세한 내용은 다음과 같습니다.
모델
public class ManagePeopleModel
{
public List<PersonModel> People { get; set; }
... any other properties
}
public class PersonModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
... any other properties
}
상위 표시
이 보기에는 다음과 같은 내용이 포함됩니다.
- 반복해야 할 사람들의 기록
- 개인을 편집해야 할 때 모달로 채워지는 빈 div
- 일부 JavaScript가 모든 Ajax 호출을 처리합니다.
@model ManagePeopleModel
<h1>Manage People</h1>
@using(var table = Html.Bootstrap().Begin(new Table()))
{
foreach(var person in Model.People)
{
<tr>
<td>@person.Id</td>
<td>@Person.Name</td>
<td>@person.Age</td>
<td>@html.Bootstrap().Button().Text("Edit Person").Data(new { @id = person.Id }).Class("btn-trigger-modal")</td>
</tr>
}
}
@using (var m = Html.Bootstrap().Begin(new Modal().Id("modal-person")))
{
}
@section Scripts
{
<script type="text/javascript">
// Handle "Edit Person" button click.
// This will make an ajax call, get information for person,
// put it all in the modal and display it
$(document).on('click', '.btn-trigger-modal', function(){
var personId = $(this).data('id');
$.ajax({
url: '/[WhateverControllerName]/GetPersonInfo',
type: 'GET',
data: { id: personId },
success: function(data){
var m = $('#modal-person');
m.find('.modal-content').html(data);
m.modal('show');
}
});
});
// Handle submitting of new information for Person.
// This will attempt to save new info
// If save was successful, it will close the Modal and reload page to see updated info
// Otherwise it will only reload contents of the Modal
$(document).on('click', '#btn-person-submit', function() {
var self = $(this);
$.ajax({
url: '/[WhateverControllerName]/UpdatePersonInfo',
type: 'POST',
data: self.closest('form').serialize(),
success: function(data) {
if(data.success == true) {
$('#modal-person').modal('hide');
location.reload(false)
} else {
$('#modal-person').html(data);
}
}
});
});
</script>
}
부분 표시
이 보기에는 사용자에 대한 정보로 채워지는 모달(modal)이 포함되어 있습니다.
@model PersonModel
@{
// get modal helper
var modal = Html.Bootstrap().Misc().GetBuilderFor(new Modal());
}
@modal.Header("Edit Person")
@using (var f = Html.Bootstrap.Begin(new Form()))
{
using (modal.BeginBody())
{
@Html.HiddenFor(x => x.Id)
@f.ControlGroup().TextBoxFor(x => x.Name)
@f.ControlGroup().TextBoxFor(x => x.Age)
}
using (modal.BeginFooter())
{
// if needed, add here @Html.Bootstrap().ValidationSummary()
@:@Html.Bootstrap().Button().Text("Save").Id("btn-person-submit")
@Html.Bootstrap().Button().Text("Close").Data(new { dismiss = "modal" })
}
}
컨트롤러의 액션
public ActionResult GetPersonInfo(int id)
{
var model = db.GetPerson(id); // get your person however you need
return PartialView("[Partial View Name]", model)
}
public ActionResult UpdatePersonInfo(PersonModel model)
{
if(ModelState.IsValid)
{
db.UpdatePerson(model); // update person however you need
return Json(new { success = true });
}
// else
return PartialView("[Partial View Name]", model);
}
에 대한 으로 Dimitrys를 사용합니다.Ajax.BeginForm적어도 MVC > 5에서는 동작합니다(4개는 테스트되지 않았습니다).
다른 답변과 같이 모델을 작성합니다.
"상위 보기"에서는 표를 사용하여 데이터를 표시할 수 있습니다.을 사용하다 그
id.- - - 단, 및 대응하는 javascript 자리 표시자.<table> @foreach (var item in Model) { <tr> <td id="editor-success-@item.Id"> @Html.Partial("dataRowView", item) </td> </tr> } </table> <div class="modal fade" id="editor-container" tabindex="-1" role="dialog" aria-labelledby="editor-title"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content" id="editor-content-container"></div> </div> </div> <script type="text/javascript"> $(function () { $('.editor-container').click(function () { var url = "/area/controller/MyEditAction"; var id = $(this).attr('data-id'); $.get(url + '/' + id, function (data) { $('#editor-content-container').html(data); $('#editor-container').modal('show'); }); }); }); function success(data,status,xhr) { $('#editor-container').modal('hide'); $('#editor-content-container').html(""); } function failure(xhr,status,error) { $('#editor-content-container').html(xhr.responseText); $('#editor-container').modal('show'); } </script>
데이터 테이블 행의 "display-success-id"에 주목합니다.
dataRowView는 모델 항목의 프레젠테이션을 포함하는 부분입니다.@model ModelView @{ var item = Model; } <div class="row"> // some data <button type="button" class="btn btn-danger editor-container" data-id="@item.Id">Edit</button> </div>)을합니다.
$('.editor-container').click(function () ...).@model Model <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> <h4 class="modal-title" id="editor-title">Title</h4> </div> @using (Ajax.BeginForm("MyEditAction", "Controller", FormMethod.Post, new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "POST", UpdateTargetId = "editor-success-" + @Model.Id, OnSuccess = "success", OnFailure = "failure", })) { @Html.ValidationSummary() @Html.AntiForgeryToken() @Html.HiddenFor(model => model.Id) <div class="modal-body"> <div class="form-horizontal"> // Models input fields </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <button type="submit" class="btn btn-primary">Save</button> </div> }
여기서 마법이 일어납니다.AjaxOptions편집 후 UpdateTargetId가 데이터 행을 대체하고 실패 시 및 성공 시 모달 제어가 이루어집니다.
즉, 편집이 성공하고 오류가 없을 때만 모달은 닫힙니다.그렇지 않으면 Ajax 포스트 후에 모달은 오류 메시지(예: 검증 요약)를 표시하기 위해 표시됩니다.
하지만 어떻게 하면 에러가 있는지 알 수 있을까요?이것은 컨트롤러 부품입니다.스텝 5 에서 다음과 같이 response.status code 를 변경합니다.
부분 편집 모달에 대응하는 컨트롤러 액션 방식
[HttpGet] public async Task<ActionResult> EditPartData(Guid? id) { // Find the data row and return the edit form Model input = await db.Models.FindAsync(id); return PartialView("EditModel", input); } [HttpPost, ValidateAntiForgeryToken] public async Task<ActionResult> MyEditAction([Bind(Include = "Id,Fields,...")] ModelView input) { if (TryValidateModel(input)) { // save changes, return new data row // status code is something in 200-range db.Entry(input).State = EntityState.Modified; await db.SaveChangesAsync(); return PartialView("dataRowView", (ModelView)input); } // set the "error status code" that will redisplay the modal Response.StatusCode = 400; // and return the edit form, that will be displayed as a // modal again - including the modelstate errors! return PartialView("EditModel", (Model)input); }
이와 같이 Modal 창에서 Model 데이터 편집 중 오류가 발생하면 MVC의 Validations Summary 메서드를 사용하여 Modal에 오류가 표시되지만 변경이 정상적으로 커밋되면 변경된 데이터 테이블이 표시되고 Modal 창이 사라집니다.
주의: Ajax 옵션이 작동하므로 번들 구성을 바인드하도록 지시해야 합니다.jquery.unobtrusive-ajax.js(NuGet에 의해 설치 가능):
bundles.Add(new ScriptBundle("~/bundles/jqueryajax").Include(
"~/Scripts/jquery.unobtrusive-ajax.js"));
인$('.editor-container').click(function (){}),해선 안된다var url = "/area/controller/MyEditAction";있다var url = "/area/controller/EditPartData";?
언급URL : https://stackoverflow.com/questions/16011151/mvc-4-edit-modal-form-using-bootstrap
'programing' 카테고리의 다른 글
| 로그에 WARN 메시지를 기록하지 않는 Spring @ExceptionHandler 메서드를 작성하려면 어떻게 해야 합니까? (0) | 2023.03.31 |
|---|---|
| JSON에 적합한 CLI 툴은 무엇입니까? (0) | 2023.03.31 |
| 필터링된 결과를 Angular로 강조 표시JS (0) | 2023.03.31 |
| WP 템플릿의 플러그인에서 함수를 호출하려면 어떻게 해야 합니까? (0) | 2023.03.31 |
| React-Select를 프로그래밍 방식으로 지우거나 재설정하는 방법 (0) | 2023.03.31 |