J'ai vraiment du mal à savoir comment mettre tout cela ensemble. J'ai construit des formulaires à l'intérieur de pages MVC .net à de nombreuses reprises, avec et sans validation. Et j'ai construit des formulaires en utilisant jQuery, avec et sans validation. Et j'ai construit des formes à l'intérieur d'un modal, mais jamais avec MVC.
Je comprends de ma question d'origine que parce que ce formulaire est à l'intérieur d'un modal que je devrai utiliser jQuery pour gérer la soumission. J'ai beaucoup de temps à trouver comment assembler toutes ces pièces en mouvement. Jusqu'à présent, je n'ai pas trouvé de tutoriel (ou combo de tutoriels) qui rassemble tout cela.
Voici ce dont j'ai besoin:
MODIFIER:
Merci, Jason, pour votre aide! Sur la base de vos suggestions, c'est ainsi que je l'ai fait fonctionner.
La vue parent:
Le modal:
<div class="modal fade" id="AccountEditModal" tabindex="-1" role="dialog" aria-labelledby="AccountEditModalLabel">
<div class="modal-dialog modalAccountEdit" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h3><strong>Edit Account Profile - <span class="accountname"></span></strong></h3>
</div>
<div class="modal-body">
<div id="formContent">
@Html.Partial("_AccountProfileEdit", new GEDCPatientPortal.Models.AccountProfileEditViewModel())
</div>
</div>
</div>
</div>
</div>
Et puis voici les scripts:
@section Scripts {
<script>
$(document).ready(function () {
$('#AccountEditModal').on('shown.bs.modal', function () {
$('#myInput').focus()
})
$("#AccountEditModal").on("submit", "#form-accountprofileedit", function (e) {
e.preventDefault(); // prevent standard form submission
var form = $(this);
$.ajax({
url: form.attr("action"),
method: form.attr("method"), // post
data: form.serialize(),
success: function (partialResult) {
$("#formContent").html(partialResult);
}
});
});
});
</script>
}
La vue partielle (allégée):
@using (Html.BeginForm("AccountProfileEdit", "Account", FormMethod.Post, new { id = "form-accountprofileedit", @class = "full-form" }))
{
@Html.CustomTextboxFor(model => model.Address)
<div style="text-align:right;">
<button type="submit" id="accountprofileedit-submit" name="accountprofileedit-submit" value="Edit Account" class="btn btn-primary" style="margin-left:5px;">Edit Account</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
</div>
}
Le contrôleur:
[HttpPost]
public ActionResult AccountProfileEdit(AccountProfileEditViewModel model)
{
if (ModelState.IsValid)
{
// logic to store form data in DB
}
return PartialView("_AccountProfileEdit", model);
}
Vous pouvez utiliser les scripts de validation MVC intégrés avec les annotations de données sur votre modèle
public class AccountProfileEditViewModel
{
[Display(Name = "Address")]
[Required()]
[StringLength(200)]
public string Address { get; set; }
}
Faites une vue partielle pour conserver votre formulaire modal.
_ AccountProfileEdit.cshtml
@model AccountProfileEditViewModel
@using(Html.BeginForm("AccountProfileEdit", "Account",
FormMethod.Post, new { id = "form-accountedit-appt" }) {
@Html.ValidationSummary(true)
@Html.LabelFor(m => m.Address)
@Html.TextBoxFor(m => m.Address)
@Html.ValidationMessageFor(m => m.Address)
<button type="submit">Edit</button>
}
Référencez ensuite cela dans votre boîte modale. Si vous voulez un modèle pré-rempli, vous devrez rendre une action:
<div class="modal-body" id="form-container">
@Html.Action("AccountProfileEdit", "Account", new { id=account.Id })
</div>
Si vous voulez juste un formulaire vierge, vous pouvez simplement utiliser:
<div class="modal-body" id="form-container">
@Html.Partial("_AccountProfileEdit")
</div>
L'action utilise le paramètre id
pour récupérer et remplir le modèle
[HttpGet]
public ActionResult AccountProfileEdit(int id)
{
AccountProfileEditViewModel model = db.GetAccount(id); // however you do this in your app
return PartialView("_AccountProfileEdit", model);
}
AJAX POST
Vous aurez maintenant besoin de AJAX pour soumettre ce formulaire. Si vous comptez sur une soumission de formulaire standard, le navigateur s'éloignera de votre page (et fermera votre modal).
$("#myModal").on("submit", "#form-accountedit", function(e) {
e.preventDefault(); // prevent standard form submission
var form = $(this);
$.ajax({
url: form.attr("action"),
method: form.attr("method"), // post
data: form.serialize(),
success: function(partialResult) {
$("#form-container").html(partialResult);
}
});
});
Vous devez utiliser le délégué d'événement $(staticParent).on(event, target, handler)
pour l'événement d'envoi, car le contenu du formulaire peut être remplacé ultérieurement.
Après l'action
[HttpPost]
public ActionResult AccountProfileEdit(AccountProfileEditViewModel model)
{
// Request.Form is model
if (ModelState.IsValid)
{
// do work
return PartialView("_AccountEditSuccess");
}
return PartialView("_AccountProfileEdit", model);
}
Les scripts de validation côté client devraient les empêcher de se soumettre. Mais si cela échoue ou si vous ne pouvez pas valider quelque chose sur le client, vous avez ModelState.IsValid
. Vous pouvez également invalider manuellement quelque chose côté serveur.
_ AccountEditSuccess.cshtml
Et la vue partielle "succès".
<div>Success! <button>Click to close</button></div>
Non valide est un échec, non?
Depuis votre gestionnaire de réussite AJAX
success: function(partialResult) {
$("#form-container").html(partialResult);
}
Mais le problème ici est que nous ne savons pas si vous obtenez un "succès" ou un "échec de validation". L'ajout d'un gestionnaire error: function(err){ }
n'aidera pas car l'échec de la validation est considéré comme une réponse HTTP 200 . Dans les deux cas, le contenu div est remplacé, l'utilisateur devra fermer manuellement le modal. Il existe des moyens de transmettre des données supplémentaires pour distinguer les deux conditions, mais c'est une autre réponse longue.
Pensez à mettre un iframe à l'intérieur de la division modale, au lieu de rendre partialView, de cette façon, vous pouvez développer la section modale de la même manière que vous développez des pages simples, qui soumettent, modélisent, requis, etc.
par ici:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modalAE" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h3><strong>Edit Account Profile - <span class="accountname"></span></strong></h3>
</div>
<div class="modal-body">
<iframe src='myApp/AccountProfileEdit'/>
</div>
<div class="modal-footer">
<button type="submit" id="accountprofileedit-submit" name="accountprofileedit-submit" value="Edit Account" class="btn btn-primary" style="margin-left:5px;">Edit Account</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>