わかりました、これが取引です。この問題に関連するSO)に関するいくつかの投稿を見ましたが、何もうまくいきません。
基本的に、パーシャルビューから読み込まれているドロップダウンを選択しました。以前に選択したドロップダウンに基づいて、後続の各ドロップダウンのコンテンツをフィルターしようとしています。
Divコンテナーに部分ビューへの呼び出しを配置してページをロードするだけの場合、データアノテーションからの検証は正常に機能します主に必須の属性。
ただし、ここで設定されているようにAJAXを介して同じパーシャルをロードしようとすると、必須の検証が機能しません。誰でもその後にKABOOMでフォームを投稿できます。
Successコールバックでは、クライアント側のバリデーターにフォームを再解析させる必要があると言っている人を見つけました。私はそれを試みていますが、動作していないようです。
私はこのような見方をしています...
@model Area51.Models.Workflow.AddReportableItemToBatchActionModel
@{
ViewBag.Title = "Add Reportable Item to Batch";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript">
$(function () {
var fadeDelay = 150;
$(".jqDatePicker").datepicker({
dateFormat: 'm/d/yy',
onSelect: function (date) {
$("#categoryContainer").show(fadeDelay);
}
});
$('#Category').change(function () {
RetrieveItemsForCategory();
$("#itemContainer").show(100);
});
$('#Item').live('change', function () {
RenderPartialForUOMByItem();
});
function RetrieveItemsForCategory() {
var category = $("#Category :selected").val();
$.ajax({
type: "POST",
url: '@Url.Action("RenderPartialForLocationItemsByCategory","BatchWorkflow")',
data: 'category=' + category,
success: function (result) {
$("#itemContainer").html(result.toString());
$("#itemContainer").show(100);
RebindValidation();
},
error: function (req, status, error) {
alert("Sorry! Could not request items for your selection at this time.");
}
});
}
function RenderPartialForUOMByItem() {
var item = $("#Item :selected").val();
$.ajax({
type: "POST",
url: '@Url.Action("RenderPartialForUOMByItem","BatchWorkflow")',
data: "item=" + item,
success: function (result) {
$("#quantityContainer").html(result.toString());
$("#quantityContainer").show(100);
RebindValidation();
},
error: function (req, status, error) {
alert("Sorry! Could not request items for your selection at this time.");
}
});
}
function RebindValidation() {
alert("Rebinding Validation");
$.validator.unobtrusive.parse("#frmAddItem");
}
}); // End OnLoad Event
</script>
<h3 class="pageHeader">Batch : @Model.BatchName</h3>
<div align="center">
@{Html.BeginForm("AddItemToBatch", "BatchWorkflow", null, FormMethod.Post, new { id = "frmAddItem" });}
@Html.ValidationSummary(true)
<fieldset style="width:60%">
<legend>Add an Item to the Batch</legend>
<div>
<h3>Select Date Item was Added</h3>
@Html.EditorFor(x => x.EventDate,null)
<br />
</div>
<div id="categoryContainer" style="display:none">
<hr />
<h3>Select an Inventory Category</h3>
@Html.EditorFor(x => x.Category,null)
<br />
</div>
<div id="itemContainer" style="display:none">
@* @{Html.RenderAction("RenderPartialForLocationItemsByCategory", "BatchWorkflow", new { category = Model.Category });}*@
</div>
<div id="quantityContainer" style="display:none">
@* @{Html.RenderAction("RenderPartialForUOMByItem", "BatchWorkflow", new { item = Model.Item });}*@
</div>
<div id="reportingDataContainer" style="display:none">
<hr />
<h3>What quantity of the batch was affected by this addition?</h3>
@Html.EditorFor(x => x.ConsumedWineQuantity) (Gallons)
<br />
<hr />
<h3>What was the increase in Batch Volume as a result of this addition?</h3>
@Html.EditorFor(x => x.ProducedWineQuantity) (Gallons)
</div>
<div style="display:block">
<div></div>
<span><button type="button" id="btnCancel" class="linkButton" value="Cancel" onclick="location.href='@Url.Action("Home","Home",null)';">Cancel</button></span>
<span><button type="submit" id="btnSubmit" class="linkButton" value="Add">Add Item</button></span>
</div>
</fieldset>
@{ Html.EndForm(); }
</div>
部分ビューは非常にシンプルで、基本的には次のようになります...
@model Area51.Models.Workflow.AddReportableItemToBatchActionModel
<hr />
<h3>Select the Item to Add</h3>
@Html.EditorFor(x => x.Item)
<br />
繰り返しますが、RenderPartialだけの場合、検証は正常に機能しますが、ajaxを使用して検証しようとすると、検証がなくなります。 "Rebinding Validation"アラートが発生しますが、$。validator.unobtrusive.parse( "#frmAddItem");何かをしていないようです。
誰かが私が欠けているものを手伝ってくれる?よろしくお願いします。
<=======================更新1 ======================== =====>
OK、$。validator.unobtrusive.parse( "#frmAddItem");を追加してみました。 document readyイベントの部分ビューの下部にあり、それも機能しないようです。基本的に何も変更されていません。それでもフォームを送信できました。
私はここで投稿を見つけました: http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/ は、MVCバージョンのjqvalidationは、フォームに既に検証ルールがバインドされていることを確認し、.validator呼び出しを無視します。この紳士が使用したスクリプト拡張機能を実装しました。検証は、新しい拡張機能を使用してフォームに再バインドしています。これをテストするには、フォームにhtmlを追加し、新しい拡張機能を呼び出します。これにより、新しいテキストボックスに再バインドされます。
ただし、これでも問題は完全には修正されていません。 Firebugを使用して、ajax呼び出しから返されるフィールドの実際のコンテンツを調べたところ、非常に奇妙なことがわかりました。
RenderPartialを使用してアクションを呼び出すと、次のselectが書き込まれます。
<select id="Item" name="Item" data-val-required="The Item field is required." data-val-number="The field Item must be a number." data-val="true">
ただし、同じ正確なコントローラーアクションに対してajax呼び出しを行うと、これが返されます。
<select id="Item" name="Item">
スクリプトタグを部分ビューにも追加してみましたが、問題は解決しませんでした。 ajax呼び出しが邪魔にならない検証タグを削除する理由はありますか?
<=======================更新2 ======================== =====>
さて、何が起こっていたのかというと、ドロップダウン用のエディターテンプレートがあり、それが選択リストを受け取り、それをHTML選択に変換したことです。エディターテンプレートに書き出すデータ検証属性を取得するには、フォームコンテキストが必要であると述べた投稿を見つけました。 Html.RenderPartialがフォーム内で実行されていたため、エディターテンプレートにはフォームコンテキストがありました。私がajax経由でパーシャルを呼び出そうとしたとき、操作するフォームコンテキストがなく、不平を言う代わりにデータ検証属性を書き出さなかっただけです。 SelectListDropDownのエディターテンプレートに新しいフォームコンテキストを追加すると、問題が修正されました。
@{ // fix to stop stupid crappy brad wilson mvc3 code from stripping the jq data valdiation attributes
if (ViewContext.FormContext == null)
{
ViewContext.FormContext = new FormContext();
}
}
$.validator.unobtrusive.parse("#frmAddItem");
が機能します。 ajaxを介してロードするのはパーシャル(パーシャルのフォームの下)でなければならないことに注意してください。
<form id="frmAddItem" method="POST" action="...">
<!-- all the items -->
</form>
<script type="text/javascript">
$.validator.unobtrusive.parse("#frmAddItem");
</script>
上記の推奨事項が機能しなかったので、私の経験を追加します。このソリューションは、検索エンジンからこのページにアクセスする他のユーザーを支援しました。
AjaxOptionsにOnSuccess="$.validator.unobtrusive.parse('YourFormName');"
を追加します
Ajax.ActionLinkを使用した例:
@Ajax.ActionLink("This is a test to get unobtrusive javascript working",
"Name_of_your_controller_action",
new AjaxOptions { HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "UserDiv",
OnSuccess="$.validator.unobtrusive.parse('UserDetailsForm');"
}
)
このソリューションは次の場所にあります http://blog.janjonas.net/2011-07-24/asp_net-mvc_3-ajax-form-jquery-validate-supporting-unobtrusive-client-side-validation-and- server-side-validation
私はあなたがあなたのjavascriptファイルに置くことができるこの小さなスニペットを書きました、そしてそれはajaxがロードされるすべてのあなたのフォームを処理します。
//enable unobtrusive validation for ajax loaded forms
$(document).ajaxSuccess(function (event, xhr, settings) {
//process only if html was returned
if ($.inArray('html', settings.dataTypes) >= 0) {
//will parse the element with given id for unobtrusive validation
function parseUnobtrusive(elementId) {
if (elementId) {
$.validator.unobtrusive.parse('#' + elementId);
}
}
//get the form objects that were loaded. Search within divs
//in case the form is the root element in the string
var forms = $('form', '<div>' + xhr.responseText + '</div>');
//process each form retrieved by the ajax call
$(forms).each(function () {
//get the form id and trigger the parsing.
//timout necessary for first time form loads to settle in
var formId = this.id;
setTimeout(function () { parseUnobtrusive(formId); }, 100);
});
}
});
私にとってはうまくいった別のオプション、むしろトリック。 ajax呼び出しによって返される部分ビューの先頭に次の行を追加するだけです
this.ViewContext.FormContext = new FormContext();
OnComplete
の代わりにOnSuccess
内で動作するように検証を取得することができました:
AJAXコード:
@using (Ajax.BeginForm("Index", null,
new AjaxOptions { OnSuccess = "onSuccess",
OnComplete = "onComplete"},
new { id = "mainForm" }))
そして、これが私のスクリプトです:
function onComplete(result) {
$.validator.unobtrusive.parse("#mainForm");
alert("Complete");
};