2016-09-16 2 views
2

Ich arbeite seit ein paar Tagen an diesem Thema und kann es nicht ganz so wie ich es erwarte. Ich habe viele Beispiele durchgesehen, aber ich muss etwas falsch verstehen.MVC 5 mit Bootstrap Modal von Teilansicht Validierung funktioniert nicht?

Was ich habe, ist ein Bootstrap-Modal, das mit einer Teilansicht geladen wird. Was ich versuche, ist Validierung (hoffentlich Client-Seite) mit Fehlern, die in der @ValidationSummary im Modal angezeigt werden. Das größte Problem Ich habe, ist, dass, wenn es einen Fehler gibt, anstatt im ursprünglichen modalen zu zeigen, lädt es grundlegend die modale Teilansicht in einer neuen Seite. Die Validierungszusammenfassung ist korrekt ausgefüllt, aber sie hat kein Styling plus ist zu diesem Zeitpunkt nicht im Modal.

* Hinweis: Ich benutze AJAX nicht, um das Modal im Moment zu laden. Ich werde das schließlich bekommen, aber ich bin nicht so bequem mit AJAX noch, und ich will es zuerst arbeiten lassen, dann kann ich zurück kommen und in AJAX umgestalten.

_Layout.cshtml - Ich habe ein Beispiel gefunden, das besagt, dass ich das JS.unobtrusive beim Laden des Modal laden musste. Ich nehme an, Ich mache das richtig, aber ich könnte etwas dort vermissen.

<div id="modal-container" class="modal fade"> 
    <div class="modal-dialog"> 
     <div class="modal-content"> 
     </div> 
    </div> 
</div> 


@Scripts.Render("~/bundles/jquery") 
@Scripts.Render("~/bundles/bootstrap") 
@RenderSection("scripts", required: false) 


<script type="text/javascript"> 

    //**** Bootstrap Modal - used with Partial Views *********************** 
    $(function() { 
     // Initalize modal dialog 
     // attach modal-container bootstrap attributes to links with .modal-link class. 
     // when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog. 
     $('body').on('click', '.modal-link', function (e) { 
      e.preventDefault(); 
      $(this).attr('data-target', '#modal-container'); 
      $(this).attr('data-toggle', 'modal'); 

      //load the unobtrusive JS code 
      $jQval.unobtrusive.parse($modal-container); 

      var $form = $modal-container.find("form"); 
      $.validator.unobtrusive.parse($form); 

     }); 

     // Attach listener to .modal-close-btn's so that when the button is pressed the modal dialog disappears 
     $('body').on('click', '.modal-close-btn', function() { 
      $('#modal-container').modal('hide'); 
     }); 

     //clear modal cache, so that new content can be loaded 
     $('#modal-container').on('hidden.bs.modal', function() { 
      $(this).removeData('bs.modal'); 
     }); 

     $('#CancelModal').on('click', function() { 
      return false; 
     }); 
    }); 

_PasswordReset.cshtml

div class="modal-header"> 
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> 
    <h4>Reset your Password</h4> 
</div> 
<div class="modal-body"> 
    <div class="form-horizontal"> 
     @using (Html.BeginForm("PasswordReset", "Member", FormMethod.Post)) 
     { 
      @Html.AntiForgeryToken() 
      @Html.ValidationSummary(false, "", new { @class = "alert alert-danger" }) 

      <!-- BEGIN HIDDEN FIELDS AREA --> 
      @Html.HiddenFor(model => model.MemberId) 
      <!-- END HIDDEN FIELDS AREA --> 

      <div class="form-group"> 
       <label class="control-label col-xs-3">Password</label> 
       <div class="col-md-9"> 
        @Html.TextBoxFor(c => c.Password, new { Class = "form-control", placeholder = "New Password", autofocus = "" }) 
       </div> 
      </div> 
      <div class="form-group"> 
       <label class="control-label col-xs-3">Confirm</label> 
       <div class="col-md-9"> 
        @Html.TextBoxFor(c => c.PasswordConfirm, new { Class = "form-control", placeholder = "Confirm Password" }) 
       </div> 
      </div> 
      <div class="form-group"> 
       <div class="col-xs-offset-3 col-xs-9"> 
        <button type="submit" id="approve-btn" class="btn btn-primary"> 
         Reset 
        </button>&nbsp;&nbsp; 

        <input type="button" class="btn btn-default" value="Cancel" data-dismiss="modal" /> 
       </div> 
      </div> 
     } 
    </div> 
</div> 

-Controller - Ich gehe davon aus, dass, wenn das Modell nicht gültig ist, dann soll ich einen PartialView zurücklaufen, da das, was ich geladen in das Modal zuerst?

public ActionResult PasswordReset(MemberViewModel vm) 
{ 
    MemberPasswordReset model = new MemberPasswordReset(); 
    model.MemberId = vm.MemberId; 

    return PartialView("_PasswordReset", model); 
} 

[HttpPost] 
[ValidateAntiForgeryToken] 
public async System.Threading.Tasks.Task<ActionResult> PasswordReset(MemberPasswordReset model) 
{ 
    if (!ModelState.IsValid) 
    { 
     return PartialView("_PasswordReset", model); 
    } 

    ApplicationDbContext context = new ApplicationDbContext(); 
    UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(context); 
    UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(userStore); 

    String userId = User.Identity.GetUserId(); 
    String hashedNewPassword = UserManager.PasswordHasher.HashPassword(model.Password); 

    ApplicationUser currentUser = await userStore.FindByIdAsync(userId); 
    await userStore.SetPasswordHashAsync(currentUser, hashedNewPassword); 
    await userStore.UpdateAsync(currentUser); 

    return RedirectToAction("MyAccount");   
} 

Ansichtsmodell

public class MemberPasswordReset 
{ 
    public string Password { get; set; } 

    [Compare("Password", ErrorMessage = "Confirm password doesn't match.")] 
    public string PasswordConfirm { get; set; } 

    public int MemberId { get; set; } 
} 

Bundle.config

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
      "~/Scripts/jquery-{version}.js", 
      "~/Scripts/jquery.validate.js", 
      "~/Scripts/jquery.validate.unobtrusive.js")); 

Antwort

1

Sie können die Teilansicht wie gibt die Teilansicht nur passieren zurück - nicht der Ansicht, + die geladene Teilansicht innerhalb des Modal. Also, was dein Sehen gerade richtig ist.

Sie müssen eine JSON-Antwort mit AJAX zurückgeben, damit sie innerhalb der Teilansicht des Modales überprüft wird.

Wenn der Modellstatus nicht gültig ist, geben Sie die Schlüssel/Wert-Paare des Modellstatus zurück. Ein gutes Startbeispiel ist hier: Example

Sobald dies an Ihre Ansicht gesendet wurde, können Sie mit jquery die Modellfehler (falls vorhanden) an den Validierungszusammenfassungsbereich anfügen.

EDIT:

Beispiel wie gewünscht -

-Controller

public class HomeController : BaseController 
{ 
    [HttpPost] 
    public ActionResult Edit(EditViewModel vm) 
    { 
     if(ModelState.IsValid) 
     { 
      //do stuff 
      return Json(new 
      { 
       status = "success" 
       //return values if needed 
      } 
     } 
     return Json(new 
     { 
      status = "failure", 
      formErrors = ModelState.Select(kvp => new { key = kvp.Key, errors = kvp.Value.Errors.Select(e => e.ErrorMessage)})}); 
     } 
    } 
} 

Ansicht

@using (Ajax.BeginForm("Edit", new AjaxOptions { OnSuccess = "onChangeSuccess"})) 
{ 
    //Modal header, body, footer 
    //Make sure your form fields actually contain their Razor validation fields 
} 

JQu ery

function onChangeSuccess(data) { 

    if (data.status === "success") { 
     $("#modalcontent").modal('hide'); 
     $("#message-area").html(data.view); 
    } 
    $.each(data.formErrors, function() { 
     $("[data-valmsg-for=" + this.key + "]").html(this.errors.join()); 
    }); 
} 
+0

Danke .... kennen Sie ein Beispiel von diesem in einem modalen implementiert? – Caverman

+0

Bitte siehe bearbeiten. – Benthon

+0

Danke! Ich werde es versuchen. – Caverman

Verwandte Themen