2011-02-25 29 views
7

Después de actualizar a JQuery 1.5 y posterior 1.5.1, mi validación de comparación falla. Estoy usando JQuery.Validate 1.7. Mi modelo de vista tiene las siguientes anotaciones de datos:JQuery 1.5 breaks Compare Validate (JQuery Validate 1.8)

/// <summary> 
/// Gets or sets the full name. 
/// </summary> 
/// <value>The full name.</value> 
[Required] 
[Display(Name = "fullname", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))] 
public string FullName { get; set; } 

/// <summary> 
/// Gets or sets the email. 
/// </summary> 
/// <value>The email.</value> 
[DataType(DataType.EmailAddress)] 
[Display(Name = "email", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))] 
[Required(ErrorMessageResourceName = "EmailRequired", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))] 
[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages), ErrorMessageResourceName = "EmailInvalid")] 
public string Email { get; set; } 

/// <summary> 
/// Gets or sets the password. 
/// </summary> 
/// <value>The password.</value> 
[DataType(DataType.Password)] 
[Display(Name = "password", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))] 
[Required(ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))] 
[ValidatePasswordLengthAttribute(ErrorMessageResourceName = "PasswordLength", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))] 
public string Password { get; set; } 

/// <summary> 
/// Gets or sets the confirm password. 
/// </summary> 
/// <value>The confirm password.</value> 
[DataType(DataType.Password)] 
[Display(Name = "confirmPassword", ResourceType = typeof(Milkshake.Commerce.Model.Resources.Text))] 
[Required(ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))] 
[Compare("Password", ErrorMessageResourceName = "PasswordsMustMatch", ErrorMessageResourceType = typeof(Milkshake.Commerce.Model.Resources.ValidationMessages))] 
public string ConfirmPassword { get; set; } 

Cualquiera que sea el valor entro, los campos de contraseña no son idénticos.

ACTUALIZACIÓN - ASP.NET AntiForgeryToken se mete en problemas.

Después de perder el tiempo en el establecimiento de puntos de interrupción FireBug, me di cuenta de que en la función de validación equalTo, a partir de la línea de 1065 en jquery.validate.js, el elemento objetivo que se encuentra, no es el campo Contraseña - pero el que __RequestVerificationToken ASP.NET MVC escribe cuando utiliza el ayudante Html.AntiForgeryToken().

Eso significa que ni siquiera estamos comparando los elementos de entrada correctos. Para solucionar este problema, he añadido un truco sucio para el archivo jquery.validate.js:

// http://docs.jquery.com/Plugins/Validation/Methods/equalTo 
equalTo: function (value, element, param) { 
    // bind to the blur event of the target in order to revalidate whenever the target field is updated 
    // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 
    var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { 
     $(element).valid(); 
    }); 

    if ($(target).is("input[type=hidden]") && $(target).attr("name") == "__RequestVerificationToken") { 
     var otherElementId = $(element).attr("id"); 
     var underScoreIndex = otherElementId.indexOf("_"); 
     otherElementId = otherElementId.substring(0, underScoreIndex + 1); 
     otherElementId += $(element).attr("data-val-equalto-other").substring(2); 

     target = $("#" + otherElementId); 
    } 

    return value == target.val(); 
} 

Este truco, toma el valor de los datos-val-equalto-otro atributo, y lo mezcla con su propio ID, para encontrar el elemento de entrada correcto No funcionará en todos los casos. Pero funciona para mí, en el caso anterior.

Respuesta

11

he encontrado que esto es debido a un error en jquery.validate.unobtrusive.js

El código en discreto añade un adaptador equalto que trata de encontrar el elemento coincidente por su atributo de nombre, usando el siguiente código:

element = $(options.form).find(":input[name=" + fullOtherName + "]")[0]; 

la variable fullOtherName es a menudo (y probablemente siempre) de espacio de nombres con un punto, por lo que la sele jQuery ctor devuelve demasiadas entradas y selecciona la primera. El período debe ser escapado con .replace, que le da ("" '\\'.):

element = $(options.form).find(":input[name=" + fullOtherName.replace(".", "\\.") + "]")[0]; 

existe una construcción similar unas líneas más bajo, y también tendrá que ser fija (así como el Javascript minificado).

+0

¡Funciona! Me pregunto si este error se ha archivado en algún lugar del universo de Microsoft. Debería informarlo a través de Microsoft Connect, para que esto se solucione en la próxima versión. – MartinHN

+0

Se ha corregido en el código. Gracias. http://connect.microsoft.com/VisualStudio/feedback/details/665793/jquery-unobtrusive-validate-equalto-fails-with-compare-attribute – jsgoupil

+1

¡Esto fue muy útil! Sin embargo, en mi caso tuve que cambiarlo a element = $ (options.form) .find (": input [name = '" + fullOtherName.replace (".", "\\.") + "']") [0]; observe las comillas simples alrededor del valor inyectado. ¡Y no olvides arreglarlo en la versión reducida! :) –

0

De http://bassistance.de/jquery-plugins/jquery-plugin-validation/

Tenga en cuenta: La última versión no es, sin embargo, , compatible con jQuery 1.5.x. Usted puede encontrar una versión compatible en el GitHub repository.

Sin embargo, ninguna de las ramas que funciona para mí ...

+0

En realidad, ni siquiera funciona con 1.5. Creo que tenemos que esperar a que arreglen los problemas :( – MartinHN

+0

Encontré algo de información nueva, échale un vistazo arriba. – MartinHN

+0

¡Salud, Martin! Mi problema es que no uso el token antiforgery ;-) –

0

En respuesta a la actualización de MartinHN, me he encontrado con el mismo problema y apliqué la misma solución. Como estoy usando plantillas de editor anidado, tuve varios underscrores en mi otherElementId y cambié su código para usar lastIndexOf en vez de indexOf. P.ej.

var underScoreIndex = otherElementId.indexOf("_"); 

se cambió a:

var underScoreIndex = otherElementId.lastIndexOf("_"); 
0

Parece que si nos fijamos en MVC4 nuevo código. Puede ver la nueva versión de jquery.validate.unobtrusive.js: http://code.msdn.microsoft.com/ASPNET-MVC-4-Mobile-e99ed0ed/sourcecode?fileId=49443&pathId=640259357 Si haces un diff. Es exactamente lo mismo que la versión MVC3, excepto con los cambios menores mencionados anteriormente hechos de otra manera. Por lo tanto, lo único que debe hacer es reemplazar su jquery.validate.unobtrusive.js con el del ejemplo de código y todo funcionará.

Para que lo sepas. Estoy usando Jquery 1.6.4 con Jquery mobile 1.0.1

2

Si todavía es relevante, tuve el mismo problema, actualicé todos los scripts y ahora funciona. Uso de lo siguiente: Jquery 1.8 (versión oficial de su cdn), validación Jquery 1.9 y jquery discreta validación del último paquete provisto por microsoft on nunget (que, extrañamente, obtiene la validación jquery 1.8 y no 1.9). Dios bendiga a Microsoft y el desastre que logra hacer con 3 archivos de script: \

1

Puede usar las versiones más recientes de jquery y jquery.validate de Microsoft CDN. No puedo ver una versión actualizada de jquery.validate.unobtrusive.min.js.

La versión de jquery.validate.unobtrusive.min.js que se envía con MVC4 funciona bien.

<!-- Scripts --> 
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> 
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.10.0/jquery.validate.min.js"></script> 
<!-- ToDo: Will Microsoft fix this on the CDN? --> 
<script type="text/javascript" src="@Url.Content("~/Scripts/Frameworks/jquery.validate.unobtrusive.min.js")"></script> 
Cuestiones relacionadas