MVC 3 jQuery Validación/globalización de número/campo decimal
validation asp.net-mvc-3 (9)
Al utilizar globalization culture = "da-DK" en el archivo Web.config, la validación de jQuery no funciona.
En Dinamarca, usamos la notación 19,95 en lugar de la forma estadounidense 19,95 cuando escribimos un precio por producto, y eso me ha dado un problema que no puedo resolver.
Empecé VS2010, el nuevo proyecto MVC 3, agregué un HomeController, una clase de producto y una vista de edición estándar simple, y el error ya está allí.
Clase de producto:
public class Product
{
public string name { get; set; }
public string itemNo { get; set; }
public decimal price { get; set; }
}
HomeController:
public class homeController : Controller
{
public ActionResult Index()
{
var product1 = new Product { name = "Testproduct", itemNo = "PRD-151541", price = 19 };
return View(product1);
}
}
Vista de índice:
@model WebUI.DomainModel.Product
<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>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Product</legend>
<div class="editor-label">
@Html.LabelFor(model => model.name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.name)
@Html.ValidationMessageFor(model => model.name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.itemNo)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.itemNo)
@Html.ValidationMessageFor(model => model.itemNo)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.price)
@Html.ValidationMessageFor(model => model.price)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
El resultado:
Lamentablemente, no puedo enviar una imagen aquí, así que siga este enlace para ver el resultado: http://www.designvision.dk/temp/mvc3_razor_validation_error.gif
SO - cuando se ejecuta el sitio web, el campo se establecerá en 19,00, que ES la definición de cultura correcta, pero al intentar guardar, la validación falla.
Por favor ayuda...
Sin complementos
Creo que la forma más sencilla de solucionar esto sin ningún complemento es anulando la validación predeterminada, como esta:
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
var regex = /^(/d*)(/,/d{1,2})?$/; //99999,99
return regex.test(value);
}
</script>
Si miras el código fuente de jquery.validate.js
, verás que solo prueba una expresión regular como el código anterior, y valida si el elemento es opcional:
@shatl tiene la respuesta correcta a partir de hoy. Tenga en cuenta que para el atributo de rango necesitará un truco que se muestra a continuación. El código completo para agregar se muestra a continuación:
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="~/Scripts/globalize.js"></script>
<script type="text/javascript" src="~/Scripts/globalize.culture.fr-FR.js"></script>
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
return this.optional(element) ||
!isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture(''fr-FR'');
});
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
//Use the Globalization plugin to parse the value
var val = $.global.parseFloat(value);
return this.optional(element) || (
val >= param[0] && val <= param[1]);
}
});
</script>
}
Gracias por esta página, me salvó un montón de problemas, tuve que arreglar el código de globalización como siempre. La cultura sueca no acepta punto como separador, pero como parseFloat utiliza los puntos de análisis javasacript subyacentes, se aceptará como separador decimal, pero estos serán rechazados. Para solucionar esto, anulo el parseFloat como este
Globalize.orgParaseFloat = Globalize.parseFloat;
Globalize.parseFloat = function(value) {
var culture = this.findClosestCulture();
var seperatorFound = false;
for (var i in culture.numberFormat) {
if (culture.numberFormat[i] == ".") {
seperatorFound = true;
}
}
if (!seperatorFound) {
value = value.replace(".", "NaN");
}
return this.orgParaseFloat(value);
};
He abierto un boleto en su Github así que tal vez esto será arreglado
Podría probar el plugin jQuery Globalization de Microsoft:
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.glob.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/globinfo/jquery.glob.da-dk.js")" type="text/javascript"></script>
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
return !isNaN($.parseFloat(value));
}
$(function () {
$.preferCulture(''da-DK'');
});
</script>
El plugin fue renombrado y movido, debes usar Globalize (Mar 2012)
<script src="@Url.Content("~/Scripts/jquery.globalize/globalize.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.globalize/cultures/globalize.culture.da-DK.js")" type="text/javascript"></script>
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
return !isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture(''da-DK'');
});
</script>
más sobre esto en la publicación de blog de Scott Hanselman
Script actualizado para la versión actual de Globalize con soporte de elementos opcionales
$.validator.methods.number = function (value, element) {
return this.optional(element) || !isNaN(Globalize.parseFloat(value));
}
$(function () {
Globalize.culture(''%%culture%%'');
});
Solo para referencia futura, lo que funcionó para mí fue el siguiente:
Recuerde establecer la versión jQuery adecuada y la cultura correcta, que en este ejemplo es danesa.
Si no puede haber períodos en el valor, entonces elimine el comentario.
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")"
type="text/javascript"></script>
<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/jquery.globalize/globalize.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.globalize/cultures/globalize.culture.da-DK.js")"
type="text/javascript"></script>
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
// if (value.indexOf(".") >= 0) {
// return false;
// }
return (Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture(''da-DK'');
});
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
//Use the Globalization plugin to parse the value
var val = Globalize.parseFloat(value);
return this.optional(element) || (val >= param[0] && val <= param[1]);
}
});
</script>
Soy de Argentina, y estoy peleando con este problema hace mucho tiempo, usamos "," como separador decimal, si escribes "coma" la validación de JavaScript falla, pero si pones ".", el modelo recibirá una número traducido a entero (55,60 será 5560)
Resolví este problema con esta simple solución:
1st- Actualicé las bibliotecas de validación de jquery, usando nuevas direcciones de cdn de: http://jqueryvalidation.org/
los enlaces que incluí en mi javascript son los siguientes:
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/additional-methods.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/additional-methods.min.js"></script>
y si lo desea en un idioma específico (en mi caso, español) agregue esta línea también:
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/localization/messages_es.js"></script>
Reemplace ES con el idioma que desee.
2nd- Si desea permitir el teclado numérico decimal, debe reemplazar "." con "," para que funcione correctamente, agregue este código a su página para hacerlo automáticamente:
$(''#txtCurrency'').keyup(function () {
$(''#txtCurrency'').val($(''#txtCurrency'').val().replace(//./g, '',''));
});
Presto, problema resuelto.
Adiós.
Terminé siguiendo los consejos del blog de Scott Hanselman sobre este tema. Puedes leer sobre esto aquí:
Tuve que hacer algunos cambios para usar Globalize en lugar de jQuery Global (ahora jQuery Global está muerto). Escribí esto en la siguiente publicación del blog en caso de que sea útil:
http://icanmakethiswork.blogspot.co.uk/2012/09/globalize-and-jquery-validate.html
después de algunas investigaciones ... encontré una solución.
Web.config en <system.web>
add
<globalization culture="auto" uiCulture="auto" enableClientBasedCulture="true"/>
Extender la clase HtmlHelper
namespace System.Web.Mvc
{
public static class LocalizationHelper
{
public static IHtmlString MetaAcceptLanguage(this HtmlHelper html)
{
var acceptLang = HttpUtility.HtmlAttributeEncode(Thread.CurrentThread.CurrentUICulture.ToString());
return new HtmlString(string.Format("<meta name=/"accept-language/" content=/"{0}/"/>", acceptLang));
}
}
}
_Layout.cshtml al final de <head>
add
@Html.MetaAcceptLanguage();
<script type="text/javascript">
$(document).ready(function () {
var data = $("meta[name=''accept-language'']").attr("content");
$.global.preferCulture(data);
});
</script>
Después de estos cambios, puedo manipular números decimales con mi guía web.
Saludos, Giacomo