2013-04-15 38 views
6

我正在使用MVC4 &实体框架来开发Web应用程序。我有一张桌子,列举了我在数据库中拥有的所有人员。对于他们每个人,我都可以通过一个模式窗口来编辑他们的信息,这是一个部分视图。但是,当我提出一些错误信息时,我的应用程序会将我重定向到我的部分视图。我想要做的是将我的模态窗口中的错误显示为MVC 4 Modal窗口,局部视图和验证

我的行动:

[HttpGet] 
public ActionResult EditPerson(long id) 
{ 
    var person = db.Persons.Single(p => p.Id_Person == id); 

    ViewBag.Id_ProductPackageCategory = new SelectList(db.ProductPackageCategories, "Id_ProductPackageCategory", "Name", person.Id_ProductPackageCategory); 

    return PartialView("_EditPerson", person); 
} 

[HttpPost] 
public ActionResult EditPerson(Person person) 
{ 

    ViewBag.Id_ProductPackageCategory = new SelectList(db.ProductPackageCategories, "Id_ProductPackageCategory", "Name", person.Id_ProductPackageCategory); 

    if (ModelState.IsValid) 
    { 
     ModelStateDictionary errorDictionary = Validator.isValid(person); 

     if (errorDictionary.Count > 0) 
     { 
      ModelState.Merge(errorDictionary); 
      return PartialView("_EditPerson", person); 
     } 

     db.Persons.Attach(person); 
     db.ObjectStateManager.ChangeObjectState(person, EntityState.Modified); 
     db.SaveChanges(); 
     return View("Index"); 
    } 

    return PartialView("_EditPerson", person); 
} 

我的部分观点:

@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 = "table" 
        })) 
{ 

    @Html.ValidationSummary() 
    @Html.AntiForgeryToken() 

    @Html.HiddenFor(model => model.Id_Person) 

    <div class="modal-body"> 
     <div class="editor-label"> 
      First name : 
     </div> 
     <div class="editor-field"> 
      @Html.TextBoxFor(model => model.FirstName, new { maxlength = 50 }) 
      @Html.ValidationMessageFor(model => model.FirstName) 
     </div> 
     <div class="editor-label"> 
      Last name : 
     </div> 
     <div class="editor-field"> 
      @Html.TextBoxFor(model => model.LastName, new { maxlength = 50 }) 
      @Html.ValidationMessageFor(model => model.LastName) 
     </div> 
     <div class="editor-label"> 
      National number : 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.NumNat, new { maxlength = 11 }) 
      @Html.ValidationMessageFor(model => model.NumNat) 
     </div> 
     <div class="editor-label"> 
      Start date : 
     </div> 
     <div class="editor-field"> 
      @Html.TextBoxFor(model => model.StartDate, new { @class = "datepicker", @Value = Model.StartDate.ToString("yyyy/MM/dd") }) 
      @Html.ValidationMessageFor(model => model.StartDate) 
     </div> 
     <div class="editor-label"> 
      End date : 
     </div> 
     <div class="editor-field"> 
      @if (Model.EndDate.HasValue) 
      { 
       @Html.TextBoxFor(model => model.EndDate, new { @class = "datepicker", @Value = Model.EndDate.Value.ToString("yyyy/MM/dd") }) 
       @Html.ValidationMessageFor(model => model.EndDate) 
      } 
      else 
      { 
       @Html.TextBoxFor(model => model.EndDate, new { @class = "datepicker" }) 
       @Html.ValidationMessageFor(model => model.EndDate) 
      } 
     </div> 
     <div class="editor-label"> 
      Distance House - Work (km) : 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.HouseToWorkKilometers) 
      @Html.ValidationMessageFor(model => model.HouseToWorkKilometers) 
     </div> 
     <div class="editor-label"> 
      Category : 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("Id_ProductPackageCategory", "Choose one ...") 
      @Html.ValidationMessageFor(model => model.Id_ProductPackageCategory) <a href="../ProductPackageCategory/Create"> 
       Add a new category?</a> 
     </div> 
     <div class="editor-label"> 
      Upgrade? : 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Upgrade) 
      @Html.ValidationMessageFor(model => model.Upgrade) 
     </div> 
    </div> 
    <div class="modal-footer"> 
     <button class="btn btn-inverse" id="save" type="submit">Save</button> 
    </div> 
} 

</div> 

我的脚本是在索引视图:

 $('.edit-person').click(function() { 
       var id = $(this).data("id"); 
       var url = '/Person/EditPerson/'+id; 
       $.get(url, function(data) { 

        $('#edit-person-container').html(data); 
        $('#edit-person').modal('show'); 

       }); 
     }); 

而且,正如你所看到的,我有把我的文本框的大小,但在我的模式,似乎没有考虑到。有关这些问题的任何想法?

回答

2

您需要处理通过JavaScript提交的编辑表单,否则它会将您重定向到您的部分视图。

你可以做这样的事情:

$('form.edit').submit(function(e) { 

    e.preventDefault(); 

    $.ajax({ 
     type: 'POST', 
     url: '/Person/EditPerson/' 
     data: { person: $(this).serialize() }, 
     success: function(data) { 

      /* Add logic to check if successful edit or with errors. Or just return true when edit is successful. */ 

      $('#edit-person-container').html(data); 
     } 
    }); 

}); 
+0

感谢您的回答,我会尝试并让您知道。 – Traffy

9

您必须手动触发这是动态加载到你的HTML页面表单上的验证。

试试这个:

在视图使用Ajax.ActionLink的局部视图的内容加载到您的对话框容器,以避免不必要的JavaScript。

@Ajax.ActionLink("AjaxLink", "EditPerson", new { PersonID = model.Id_Person }, new AjaxOptions { UpdateTargetId = "myModalDialog", HttpMethod = "Post",OnSuccess="OpenDialog(myModalDialog)" }) 

<div id="myModalDialog" title="" style="display: none"> 
</div> 

在你的JS文件做

function OpenDialog(DialogContainerID) 
{ 
    var $DialogContainer = $('#' + DialogContainerID); 
    var $jQval = $.validator; //This is the validator 
    $jQval.unobtrusive.parse($DialogContainer); // and here is where you set it up. 
    $DialogContainer.modal(); 

    var $form = $DialogContainer.find("form"); 
    $.validator.unobtrusive.parse($form); 

    $form.on("submit", function (event) 
    { 
      var $form = $(this); 

      //Function is defined later... 
      submitAsyncForm($form, 
      function (data) 
      { 
        $DialogContainer.modal("hide"); 
        window.location.href = window.location.href; 

      }, 
      function (xhr, ajaxOptions, thrownError) 
      { 
        console.log(xhr.responseText); 
        $("body").html(xhr.responseText); 
      }); 
      event.preventDefault(); 
    }); 
} 

//This is the function that will submit the form using ajax and check for validation errors before that. 
function submitAsyncForm($formToSubmit, fnSuccess, fnError) 
{ 
     if (!$formToSubmit.valid()) 
       return false; 

     $.ajax({ 
       type: $formToSubmit.attr('method'), 
       url: $formToSubmit.attr('action'), 
       data: $formToSubmit.serialize(), 

       success: fnSuccess, 
       error: fnError 

     }); 

} 
+0

谢谢。我应该把这个函数放到我的局部视图中吗? – Traffy

+2

@Traffy在这里我已经添加了脚本的完整用法,以更好地解释我自己。 – Mortalus

+0

好的,谢谢,我会尝试并让你知道,谢谢。 – Traffy

0

这为我工作:

//allow the validation framework to re-prase the DOM 
jQuery.validator.unobtrusive.parse();  
//or to give the parser some context, supply it with a selector 
//jQuery validator will parse all child elements (deep) starting 
//from the selector element supplied 
jQuery.validator.unobtrusive.parse("#formId"); 
// and then: 
$("#formId").valid() 

Here

0

两者你已经添加下面的脚本到布局或包含部分的视图? jquery.unobtrusive-ajax.min.js。这对于异步请求是必需的,并且默认情况下不添加,但存在于脚本下的新解决方案中。