programing

MVC 4 부트스트랩을 사용한 모달폼 편집

goodjava 2023. 3. 31. 22:24

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개는 테스트되지 않았습니다).

  1. 다른 답변과 같이 모델을 작성합니다.

  2. "상위 보기"에서는 표를 사용하여 데이터를 표시할 수 있습니다.을 사용하다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"에 주목합니다.

  1. 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>
    
  2. )을합니다.$('.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">&times;</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 를 변경합니다.

  1. 부분 편집 모달에 대응하는 컨트롤러 액션 방식

    [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