I'm trying to validate a dynamically generated Radio Button Groups for a Survey that the answers and questions are dynamically generated too, but when I try to submit the form the validator message appears but isn't functioning right because I'm making a mistake with the jQuery implementation or the method of validation.
I want to validate (unobstrusive) each answer by question generated in the form after submit, like the other field's (CodChofer, CodUsuario).
I have this model:
[Table("Encuesta")]
public class Encuesta
{
[Key]
public int IdEncuesta { get; set; }
[Required(ErrorMessage = "El código del chofer es requerido.")]
[Display(Name = "Código de chofer")]
[MaxLength(7, ErrorMessage = "Código de chofer debe ser de máximo 7 dígitos.")]
[MinLength(7, ErrorMessage = "Código de chofer debe ser de mínimo 7 dígitos.")]
public string CodUsuario { get; set; }
[Required(ErrorMessage = "El código de usuario es requerido.")]
[Display(Name = "Código de usuario")]
[MaxLength(7, ErrorMessage = "Código de usuario debe ser de máximo 7 dígitos.")]
[MinLength(7, ErrorMessage = "Código de usuario debe ser de mínimo 7 dígitos.")]
public string CodChofer { get; set; }
public virtual ICollection<Pregunta> Preguntas { get; set; }
[MultipleRequiredValues(ErrorMessage = "Debe elegir una respuesta por pregunta")]
public virtual ICollection<Respuesta> Respuestas { get; set; }
public string Observaciones { get; set; }
[ReadOnly(true)]
[DataType(DataType.Date)]
public DateTime Fecha { get; set; }
[ReadOnly(true)]
public int Puntuacion { get; set; }
public Encuesta()
{
this.Fecha = DateTime.Now;
}
}
I have this custom validator:
namespace SSU.DAL.Validators
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class MultipleRequiredValuesAttribute : RequiredAttribute, IClientValidatable
{
#region IClientValidatable Members
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var clientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = base.ErrorMessage,
ValidationType = "multiplerequiredvalues"
};
return new[] { clientValidationRule };
}
#endregion
}
}
This View:
@model SSU.DAL.Models.Encuesta
<script type="text/javascript">
function calcscore() {
var score = 0;
$(".calc:checked").each(function () {
score += parseInt($(this).val(), 10);
});
$("input[name=total]").val(score)
}
$().ready(function () {
$(".calc").change(function () {
calcscore()
});
});
(function ($) {
$.validator.addMethod('multiplerequiredvalues', function (value, element) {
if ($(element).is(':visible')) {
var returnVal = true;
var name = $(element).attr('name');
var elements;
if ($(element).is('input')) {
elements = $('input[name=' + name + ']');
}
else {
elements = $('select[name=' + name + ']');
}
elements.each(function () {
if ($(this).is(':visible')) {
returnVal = $(this).val() != "" && $(this).val() != null;
}
});
return returnVal;
}
else {
return true;
}
});
$.validator.unobtrusive.adapters.addBool("multiplerequiredvalues");
} (jQuery));
</script>
@* This partial view defines form fields that will appear when creating and editing entities *@
<div>
<div class="editor-label">
@Html.LabelFor(model => model.CodUsuario)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CodUsuario)
@Html.ValidationMessageFor(model => model.CodUsuario)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.CodChofer)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CodChofer)
@Html.ValidationMessageFor(model => model.CodChofer)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Observaciones)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Observaciones)
@Html.ValidationMessageFor(model => model.Observaciones)
</div>
</div>
<div>
<div class="editor-field">
</div>
<table id="preguntasRespuestas" class="table table-striped">
<tr>
<th>
Preguntas
</th>
<th>
Respuestas
</th>
</tr>
<tr>
@if (Model == null)
{
<td>
@Html.Label("No hay preguntas/respuestas para mostrar.")
</td>
}
else
{
foreach (var preguntas in Model.Preguntas)
{
<tr id="@(preguntas.IdPregunta)">
<td>
@Html.DisplayFor(p => preguntas.Descripcion)
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
@foreach (var respuestas in Model.Respuestas)
{
<span style="float: left">
@Html.RadioButton("rbGrp" + (Int64)preguntas.IdPregunta, respuestas.Valor, new { @class = "calc", @validate = "required:true" })
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px">@Html.Label(respuestas.Descripcion)</span>
}
<span>@Html.ValidationMessageFor(x => x.Respuestas)</span>
</td>
</tr>
}
}
</tr>
</table>
@Html.Hidden("total")
</div>
The HTML Generated in the browser:
<!DOCTYPE html>
<html>
<head>
<title>Crear</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="" />
<meta name="author" content="" />
<link href="/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/Content/site.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.8.0.min.js" type="text/javascript"></script>
<script src="/Scripts/bootstrap.min.js" type="text/javascript"></script>
<script src="/Scripts/site.js" type="text/javascript"></script>
<script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"
type="text/javascript"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<link href="/Content/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<link href="/Content/jquery-ui-1.8.16.custom.css" rel="stylesheet" type="text/css" />
<link href="/Content/ui.jqgrid.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="/Scripts/i18n/grid.locale-en.js" type="text/javascript"></script>
<script src="/Scripts/jquery.jqGrid.min.js" type="text/javascript"></script>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="/">SSU</a>
<ul class="nav">
<li><a href="/home/?layout=standard" id="inicio">Inicio</a></li>
<li><a href="/encuestas/" id="encuestas">Encuestas</a></li>
<li><a href="/preguntas/" id="preguntas">Preguntas</a></li>
<li><a href="/respuestas/" id="respuestas">Respuestas</a></li>
</ul>
<ul class="nav pull-right">
<li><a href="#" id="user">BCNET\2007022</a></li>
</ul> </div>
</div>
</div>
<div class="container">
<h2>Crear</h2>
<form action="/encuestas/Create" method="post"> <fieldset>
<legend>Encuesta</legend>
<script type="text/javascript">
function calcscore() {
var score = 0;
$(".calc:checked").each(function () {
score += parseInt($(this).val(), 10);
});
$("input[name=total]").val(score)
}
$().ready(function () {
$(".calc").change(function () {
calcscore()
});
});
(function ($) {
$.validator.addMethod('multiplerequiredvalues', function (value, element) {
if ($(element).is(':visible')) {
var returnVal = true;
var name = $(element).attr('name');
var elements;
if ($(element).is('input')) {
elements = $('input[name=' + name + ']');
}
else {
elements = $('select[name=' + name + ']');
}
elements.each(function () {
if ($(this).is(':visible')) {
returnVal = $(this).val() != "" && $(this).val() != null;
}
});
return returnVal;
}
else {
return true;
}
});
$.validator.unobtrusive.adapters.addBool("multiplerequiredvalues");
} (jQuery));
</script>
<div>
<div class="editor-label">
<label for="CodUsuario">Código de chofer</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-required="El código del chofer es requerido." id="CodUsuario" name="CodUsuario" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="CodUsuario" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="CodChofer">Código de usuario</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-required="El código de usuario es requerido." id="CodChofer" name="CodChofer" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="CodChofer" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="Observaciones">Observaciones</label>
</div>
<div class="editor-field">
<textarea cols="20" id="Observaciones" name="Observaciones" rows="2">
</textarea>
<span class="field-validation-valid" data-valmsg-for="Observaciones" data-valmsg-replace="true"></span>
</div>
</div>
<div>
<div class="editor-field">
</div>
<table id="preguntasRespuestas" class="table table-striped">
<tr>
<th>
Preguntas
</th>
<th>
Respuestas
</th>
</tr>
<tr>
<tr id="2">
<td>
Apariencia física del chofer
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp2" name="rbGrp2" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp2" name="rbGrp2" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp2" name="rbGrp2" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp2" name="rbGrp2" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp2" name="rbGrp2" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
<tr id="3">
<td>
Velocidad adecuada
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp3" name="rbGrp3" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp3" name="rbGrp3" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp3" name="rbGrp3" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp3" name="rbGrp3" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp3" name="rbGrp3" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
<tr id="4">
<td>
Rebase oportuno
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp4" name="rbGrp4" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp4" name="rbGrp4" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp4" name="rbGrp4" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp4" name="rbGrp4" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp4" name="rbGrp4" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
<tr id="5">
<td>
Respeto por las señales de tránsito
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp5" name="rbGrp5" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp5" name="rbGrp5" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp5" name="rbGrp5" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp5" name="rbGrp5" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp5" name="rbGrp5" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
<tr id="6">
<td>
Prudencia
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp6" name="rbGrp6" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp6" name="rbGrp6" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp6" name="rbGrp6" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp6" name="rbGrp6" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp6" name="rbGrp6" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
<tr id="7">
<td>
Actitud de servicio ante el usuario
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp7" name="rbGrp7" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp7" name="rbGrp7" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp7" name="rbGrp7" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp7" name="rbGrp7" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp7" name="rbGrp7" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
<tr id="8">
<td>
Evaluación general del servicio
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp8" name="rbGrp8" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp8" name="rbGrp8" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp8" name="rbGrp8" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp8" name="rbGrp8" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp8" name="rbGrp8" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
<tr id="11">
<td>
Condiciones del vehículo
</td>
<td style="text-align: left; line-height: 15px; height: 20px">
<span style="float: left">
<input class="calc" id="rbGrp11" name="rbGrp11" type="radio" validate="required:true" value="1" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Mal">Mal</label></span>
<span style="float: left">
<input class="calc" id="rbGrp11" name="rbGrp11" type="radio" validate="required:true" value="2" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Regular">Regular</label></span>
<span style="float: left">
<input class="calc" id="rbGrp11" name="rbGrp11" type="radio" validate="required:true" value="3" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Bien">Bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp11" name="rbGrp11" type="radio" validate="required:true" value="4" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Muy_bien">Muy bien</label></span>
<span style="float: left">
<input class="calc" id="rbGrp11" name="rbGrp11" type="radio" validate="required:true" value="5" />
<br />
</span>
<span style="float: left; margin-removed 10px; margin-removed 10px"><label for="Excelente">Excelente</label></span>
<span><span class="field-validation-valid" data-valmsg-for="Respuestas" data-valmsg-replace="true"></span></span>
</td>
</tr>
</tr>
</table>
<input id="total" name="total" type="hidden" value="" />
</div>
<p>
<input type="submit" value="Crear" />
</p>
</fieldset>
</form>
<div>
<a href="/encuestas">Regresar</a>
</div>
<hr />
<footer>
<p>Banco Central de la República Dominicana</p>
</footer>
</div>
</body>
</html>
Best regards,
JAB