2013-04-15 11 views
6

Utilizzo MVC4 & Entity Framework per lo sviluppo di un'applicazione Web. Ho una tabella che elenca tutte le persone che ho nel mio DB. Per ognuna di esse, posso modificare le loro informazioni attraverso una finestra modale che è una vista parziale. Tuttavia, quando inserisco delle informazioni errate, la mia applicazione mi reindirizza alla mia vista parziale. Quello che ho voluto fare è quello di visualizzare gli errori nella mia finestra modale.MVC 4 Finestra modale, vista parziale e convalida

mia azione:

[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); 
} 

La mia visione parziale:

@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> 

Il mio script che è nella vista Index:

 $('.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'); 

       }); 
     }); 

Inoltre, come potete vedere, ho metti una taglia per le mie caselle di testo ma nel mio modale, sembra non essere presa in considerazione. Qualche idea per questi problemi?

risposta

2

È necessario gestire l'invio del modulo di modifica tramite JavaScript, altrimenti verrà reindirizzato alla vista parziale.

si può fare qualcosa di simile:

$('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

Grazie per la risposta, ci proverò e ti faccio sapere. – Traffy

9

Dovete sparare manualmente il validatore sul modulo che è stato caricato in modo dinamico nella tua pagina html.

provare questo:

nella visualizzazione uso Ajax.ActionLink per caricare il contenuto della vista parziale nel contenitore finestra di dialogo per evitare inutili 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> 

in te file di JS fare questo

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

Grazie. Dovrei semplicemente mettere questa funzione nella mia vista parziale e basta? – Traffy

+2

@Traffy Qui ho aggiunto l'uso completo della sceneggiatura per spiegarmi meglio. – Mortalus

+0

Ok, grazie, ci proverò e ti faccio sapere, grazie. – Traffy

0

Questo ha funzionato per me:

//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() 

Tratto da Here

0

Avete aggiunto il seguente script al layout o alla vista che contiene il parziale? jquery.unobtrusive-ajax.min.js. Questo è necessario per le richieste asincrone e non viene aggiunto per impostazione predefinita ma è presente in una nuova soluzione in Scripts.

Problemi correlati