私はこれをすべてまとめる方法を知ることに本当に苦労しています。検証の有無にかかわらず、.net MVCページ内にフォームを何度も作成しました。そして、jQueryを使用して、検証ありと検証なしのフォームを作成しました。また、モーダル内にフォームを作成しましたが、MVCを使用したことはありません。
元の質問 から理解できるのは、このフォームはモーダル内にあるため、jQueryを使用して送信を処理する必要があるからです。私は、これらすべての動くピースをどのようにまとめるかを考え出すのにかなりの時間を費やしています。これまでのところ、これをすべてまとめたチュートリアル(またはチュートリアルのコンボ)は見つかりませんでした。
必要なものは次のとおりです。
編集:
ジェイソン、助けてくれてありがとう!あなたの提案に基づいて、これは私がそれを機能させた方法です。
親ビュー:
モーダル:
<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>
次に、スクリプトを示します。
@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>
}
部分ビュー(スリム化):
@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>
}
コントローラー:
[HttpPost]
public ActionResult AccountProfileEdit(AccountProfileEditViewModel model)
{
if (ModelState.IsValid)
{
// logic to store form data in DB
}
return PartialView("_AccountProfileEdit", model);
}
組み込みのMVC検証スクリプトをモデルのデータ注釈とともに使用できます
_public class AccountProfileEditViewModel
{
[Display(Name = "Address")]
[Required()]
[StringLength(200)]
public string Address { get; set; }
}
_
部分的なビューを作成して、モーダルフォームを保持します。
_ 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>
}
_
次に、モーダルボックスでこれを参照します。事前に設定されたモデルが必要な場合は、アクションをレンダリングする必要があります。
_<div class="modal-body" id="form-container">
@Html.Action("AccountProfileEdit", "Account", new { id=account.Id })
</div>
_
空白のフォームが必要な場合は、次を使用できます。
_<div class="modal-body" id="form-container">
@Html.Partial("_AccountProfileEdit")
</div>
_
アクションはid
パラメーターを使用してモデルを取得し、データを取り込みます
_[HttpGet]
public ActionResult AccountProfileEdit(int id)
{
AccountProfileEditViewModel model = db.GetAccount(id); // however you do this in your app
return PartialView("_AccountProfileEdit", model);
}
_
AJAX POST
このフォームを送信するには、AJAXが必要です。標準フォームの送信に依存している場合、ブラウザはページから移動します(モーダルを閉じます)。
_$("#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);
}
});
});
_
フォームのコンテンツは後で置き換えられる可能性があるため、送信イベントにはイベントデリゲート$(staticParent).on(event, target, handler)
を使用する必要があります。
アクション後
_[HttpPost]
public ActionResult AccountProfileEdit(AccountProfileEditViewModel model)
{
// Request.Form is model
if (ModelState.IsValid)
{
// do work
return PartialView("_AccountEditSuccess");
}
return PartialView("_AccountProfileEdit", model);
}
_
クライアント側の検証スクリプトは、それらが送信されないようにする必要があります。しかし、それが何らかの理由で失敗した場合、またはクライアントで何かを検証できない場合は、_ModelState.IsValid
_があります。サーバー側の何かを手動で無効にすることもできます。
_ AccountEditSuccess.cshtml
そして、「成功」部分ビュー。
_<div>Success! <button>Click to close</button></div>
_
無効なのは失敗ですか?
あなたのAJAXあなたが持っている成功ハンドラから
_success: function(partialResult) {
$("#form-container").html(partialResult);
}
_
ただし、ここでの問題は、「成功」または「検証失敗」のどちらが発生しているかわからないことです。検証エラーはHTTP 200応答と見なされるため、error: function(err){ }
ハンドラーを追加しても役に立ちません。どちらの場合も、divコンテンツは置き換えられ、ユーザーは手動でモーダルを閉じる必要があります。 are両方の条件を区別するために追加のデータを渡す方法がありますが、それは別の長い回答の投稿です。
PartialViewをレンダリングする代わりに、モーダルdiv内にiframeを配置することを検討してください。この方法で、送信、モデル化、必要なものなどの単純なページを開発するのと同じ方法でモーダルセクションを開発できます。
こちらです:
<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>