2011-04-14 27 views
11

Estoy tratando de hacer la validación requerida en una lista de botones de opción para forzar al usuario a seleccionar una opción para continuar. La validación funciona, pero solo genera metadatos en el primer botón de opción y solo marca el primer botón de opción con la clase entrada-validación-error.ASP.NET MVC 3 validación no intrusiva y botones de radio

Ejemplo:

<p>@Html.RadioButtonFor(x => x.Choices, SomeEnum.OptionOne)</p> 
<p>@Html.RadioButtonFor(x => x.Choices, SomeEnum.OptionTwo)</p> 

resultante HTML:

<p><input class="input-validation-error" data-val="true" data-val-required="required text" type="radio" name="Choices" value="OptionOne" /></p> 
<p><input type="radio" name="Choices" value="OptionTwo" /></p> 

Quiero los dos botones de radio para obtener el error de validación de clase o que puedan poner en riesgo sesgar lo que el usuario selecciona la opción.

¿Qué puedo hacer?

+0

¿Cómo funciona su vista parece? ¿Tiene un @ Html.ValidationMessageFor (x => x.Choices)? – PussInBoots

Respuesta

-1

Lo que hice fue desactivar el css para el botón de radio y solo mostrar el mensaje de error. (no estoy seguro de IE le gusta este)

.input-validation-error input[type="radio"] 
{ 
    border: 0x solid #ff0000; 
    background-color: inherit; 
} 
7

Tenga en cuenta que el comportamiento esperado de la siguiente código

@Html.RadioButtonFor(x => x.MyEnumProperty, MyEnum.OptionOne) 
@Html.RadioButtonFor(x => x.MyEnumProperty, MyEnum.OptionTwo) 
@Html.RadioButtonFor(x => x.MyEnumProperty, MyEnum.OptionThree) 

es

<input id="MyEnumeration" type="radio" value="Option1" 
     name="MyEnumeration" 
     data-val-required="The MyEnumeration field is required." data-val="true"> 
<input id="MyEnumeration" type="radio" value="Option2" name="MyEnumeration"> 
<input id="MyEnumeration" type="radio" value="Option3" name="MyEnumeration"> 

¿Por qué? porque Html.SomethingFor(model => model.Property) está destinado a generar un elemento html para una propiedad particular. La forma en que la usa para crear más de un elemento a partir de una propiedad no es correcta.

Además, observe los ID de estos 3 botones de opción. Son bastante iguales, ¿no? ¿Es aceptable tener elementos con los mismos ID en una página html? ¡Absolutamente no! Por lo tanto, algo necesita ser arreglado.

Aunque pensé que resolver este problema es más fácil desarrollando un nuevo Método de extensión HTML (referencia 2), traté de resolverlo de otra manera (¡porque soy tan terco!).

En primer lugar, tenemos que cambiar el código de afeitar:

<div> 
    @Html.RadioButtonFor(m => m.MyEnumeration, MyEnum.Option1, new { id = "m1" }) 
    <label for="m1"> 
     OPTION 1</label> 
    @Html.RadioButtonFor(m => m.MyEnumeration, MyEnum.Option2, new { id = "m2" }) 
    <label for="m2"> 
     OPTION 2</label> 
    @Html.RadioButtonFor(m => m.MyEnumeration, MyEnum.Option3, new { id = "m3" }) 
    <label for="m3"> 
     OPTION 3</label> 
</div> 

Entonces, un pedazo de la magia JavaScript/jQuery para arreglar nuestro problema:

<script type="text/javascript"> 
    $(function() { 
     $('[name=MyEnumeration]').each(function (index) { domAttrModified(this); }); 
    }); 

    function domAttrModified(obj) { 
     //$obj = $(obj); 
     $(obj).bind('DOMAttrModified', function() { 
      if ($(obj).attr('class').indexOf('input-validation-error') != -1) 
       $(obj).parent().addClass('input-validation-error'); 
      else 
       $(obj).parent().removeClass('input-validation-error'); 
     }); 
    } 
</script> 

Cada vez que el primer botón de opción plantea una validación error, este código de JavaScript aplica la clase css de error (input-validation-error) al elemento principal de los botones de opción, que es un elemento <div>.

Y en cualquier momento el error de validación desaparece (al hacer clic en cualquiera de los elementos del botón de opción), el estilo de error se elimina del elemento principal.

Funciona muy bien en IE y FF, pero desafortunadamente no funciona en Chrome. El motivo es que Chrome no es compatible con el evento DOMAttrModified. Podemos solucionarlo utilizando esta solución: https://stackoverflow.com/a/10466236/538387, pero tal vez algún tiempo después.

Una vez más, creo que es necesario desarrollar un método de extensión HTML o mejorar y utilizar un EditorTemplate así: https://gist.github.com/973482

Referencias:

  1. https://stackoverflow.com/a/7098541/538387
  2. https://stackoverflow.com/a/3448675/538387
  3. https://gist.github.com/973482
  4. Event detect when css property changed using Jquery
4

Esto se puede realizar mediante el uso de la showErrors de devolución de llamada:

$("form").data("validator").settings.showErrors = function (errorMap, errorList) { 
    this.defaultShowErrors(); 

    $("input[type=radio][data-val=true].input-validation-error").each(function() { 
     $("input[name=" + $(this).attr('name') + "]").addClass("input-validation-error"); 
    }); 

    $("input[type=radio][data-val=true]:not(.input-validation-error)").each(function() { 
     $("input[name=" + $(this).attr('name') + "]").removeClass("input-validation-error"); 
    }); 
}; 
+0

Lamentablemente, esto da como resultado la validación del lado del cliente que ya no bloquea el POST. ¿Alguna idea de por qué? – Sprintstar

Cuestiones relacionadas