asp.net-mvc - vista - render partial view mvc 5
La validación no intrusiva no funciona en vista parcial añadida dinámicamente (2)
Actualmente estoy enfrentando un problema con la validación después de agregar contenido dinámicamente.
Tengo una vista fuertemente tipada a un modelo ( Order
). Esta orden puede tener muchos artículos. El modelo se ve algo como lo siguiente:
public class Order
{
[Key]
[HiddenInput]
public int id { get; set; }
[Display(Name = "Order Number")]
public string number { get; set; }
[Display(Name = "Order Date")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime date { get; set; }
[Required(ErrorMessage = "Beneficiary is required.")]
[Display(Name = "Beneficiary")]
public int beneficiary_id { get; set; }
[Display(Name = "Beneficiary")]
public Beneficiary beneficiary { get; set; }
[Display(Name = "Items")]
public List<Item> items { get; set; }
[Display(Name = "Payment Method")]
public List<PaymentMethod> payment_methods { get; set; }
}
Ingreso la información de la orden y también los artículos para esa orden específica. Intenté agregar un par de formas dinámicamente y finalmente seguí el camino de Steven Sanderson .
En mi opinión, tengo la información regular del pedido y luego los artículos, donde mi modelo se ve así:
@model trackmeMvc.Models.Model.Order
@{
ViewBag.Title = "Create";
Html.EnableClientValidation();
Html.EnableUnobtrusiveJavaScript();
}
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/MicrosoftMvcValidation.js")" type="text/javascript"></script>
@using (Html.BeginForm("Create", "Order", FormMethod.Post, new { @id = "create_order" }))
{
@Html.ValidationSummary(true, "Order creation was unsuccessful. Please correct the errors and try again.")
<div class="editor-label">
@Html.LabelFor(m => m.date)<req>*</req>
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.date, new { @id = "order_date" })<br />
@Html.ValidationMessageFor(m => m.date)
</div>
...
<script type="text/javascript">
$(document).ready(function () {
$("#addItem").click(function () {
var formData = $("#main_div").closest("form").serializeArray();
$.ajax({
url: "/IPO/BlankItemRow",
type: "POST",
//data: formData,
cache: false,
success: function (html) {
$("#editorRows").append(html);
//$.validator.uobtrusive.parseDynamicContent("form *");
//$("#editorRows").removeData("validator");
//$("#editorRows").removeData("unobtrusiveValidation");
//$.validator.unobtrusive.parse("#editorRows");
//$.validator.unobtrusive.parse("#create_ipo");
//$.validator.unobtrusive.parseDynamicContent($(this).first().closest("form"));
//$.validator.unobtrusive.parse($("#new_ipo_item"));
//$.validator.unobtrusive.parseElement($("#editorRows").find(".editRow:last").children().find("select"));
//$("#editorRows").find(".editRow:last").find("select").each(function () {
//alert($(this).attr("id"));
//$.validator.unobtrusive.parseElement($(this));
//$.validator.unobtrusive.parseDynamicContent($(this));
//$.validator.unobtrusive.parseDynamicContent($(this).attr("name"));
//});
//$("#editorRows").children().find(".editRows:last").find("*").each(function () {
// alert($(this).attr(''id''));
//$.validator.unobtrusive.parseDynamicContent(''input'');
//});
//var form = $(this).closest("form").attr("id");
//$(form).removeData("validator");
//$(form).removeData("unobtrusiveValidation");
//$.validator.unobtrusive.parse(form);
}
});
return false;
});
});
</script>
Esas son algunas de las cosas que probé, y nada funciona.
parseDynamicContent
el parseDynamicContent
de la aplicación de validación jquery discreta al contenido dinámico en ASP.Net MVC . Lo intenté en todos los escenarios en los que pude pensar, pero todavía no tuve suerte.
También probé el análisis regular, eliminando la validación del formulario y luego volviéndolo a aplicar, pero los elementos recién agregados no se validan:
<div id="editorRows">
@foreach (var item in Model.items)
{
@Html.Partial("_NewItem", item)
}
</div>
... y mi vista parcial se vería así:
@model trackmeMvc.Models.Model.Item
@{
Layout = "";
Html.EnableClientValidation(true);
if (this.ViewContext.FormContext == null)
{
this.ViewContext.FormContext = new FormContext();
}
}
<div class="editRow">
@using (Html.BeginCollectionItem("order_items"))
{
@Html.DropDownListFor(m => m.item_id, @items, "None", new { @style = "width:205px;", @id = "ddlItems", @class="ddlItem", @name="ddlItemList" })
@Html.ValidationMessageFor(m => m.item_id)
...
}
</div>
Entonces, lo que está sucediendo es que tengo un elemento vacío enviado desde el controlador a la vista de forma predeterminada, para mostrar una fila vacía. Ese elemento está validado, pero cualquier cosa que aparezca después de hacer clic en Agregar elemento, aparecerá otra fila, de ese parcial, pero no puedo obtener la validación. Traté de poner la validación en la vista parcial, (antes de que el documento estuviera listo en el formulario principal) y todo lo que leí apliqué, y siempre termina igual: validando la primera fila, y no las otras. Probé la validación de Steven Sanderson para ese fin, todavía sin suerte, incluso la validación de los parciales, que se encuentran en este enlace y la página que sigue, que es específica para la validación parcial ...
¿Qué debo hacer para que esta validación funcione?
Bien, voy a empezar de nuevo con una nueva respuesta aquí.
Antes de llamar a $.validator.unobtrusive.parse
, elimine el validador original y la validación no $.validator.unobtrusive.parse
del formulario de la siguiente manera:
var form = $("#main_div").closest("form");
form.removeData(''validator'');
form.removeData(''unobtrusiveValidation'');
$.validator.unobtrusive.parse(form);
Esta misma respuesta está documentada here .
Lo que funcionó para mí fue volver a aplicar el validador después de la llamada para cargar la vista parcial. En mi caso, estoy usando $.post().then()
.always()
pero podrías hacer algo similar con una devolución de llamada .always()
de una llamada AJAX.
$.post(url, model, function (data) {
//load the partial view
$("#Partial").html(data);
}).then(function () {
$("form").each(function () { $.data($(this)[0], ''validator'', false); });
$.validator.unobtrusive.parse("form");
});