MVC 3 Проверка jQuery / глобализация числа / десятичного поля
При использовании globalization culture="da-DK" в файле Web.config проверка jQuery не работает.
В Дании мы используем нотацию 19,95 вместо американской 19,95, когда пишем цену на товар, и это поставило меня перед проблемой, которую я не могу решить.
Я запустил VS2010, новый проект MVC 3, добавил homeController, класс Product и простое стандартное представление редактирования, и ошибка уже есть.
Класс продукта:
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);
}
}
Индекс просмотра:
@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>
}
Результат:
К сожалению, я не могу отправить изображение здесь - поэтому, пожалуйста, перейдите по этой ссылке, чтобы увидеть результат: http://www.designvision.dk/temp/mvc3_razor_validation_error.gif
SO - при запуске веб-сайта поле будет установлено на 19,00 - что является правильным определением культуры - но при попытке сохранения проверка не проходит.
Пожалуйста помоги...
9 ответов
Вы можете попробовать плагин jQuery Globalization от 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>
Плагин был переименован и перемещен, вы должны использовать Globalize (март 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>
Подробнее об этом в блоге Скотта Хансельмана
Обновлен скрипт для текущей версии https://github.com/jquery/globalize с поддержкой дополнительных элементов
$.validator.methods.number = function (value, element) {
return this.optional(element) || !isNaN(Globalize.parseFloat(value));
}
$(function () {
Globalize.culture('%%culture%%');
});
@shatl имеет правильный ответ на сегодняшний день. Обратите внимание, что для атрибута range вам понадобится взлом, показанный ниже. Полный код для добавления показан ниже:
@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>
}
В итоге я последовал совету в блоге Скотта Хансельмана на эту тему - вы можете прочитать об этом здесь:
Мне пришлось внести некоторые изменения, чтобы использовать Globalize вместо jQuery Global (сейчас jQuery Global мертв). Я написал это в следующем сообщении в блоге на случай, если это будет полезно:
http://icanmakethiswork.blogspot.co.uk/2012/09/globalize-and-jquery-validate.html
Просто для дальнейшего использования у меня сработало следующее:
Не забудьте установить правильную версию jQuery и правильную культуру, которая в этом примере датская.
Если в значении не может быть периодов, раскомментируйте комментарий.
<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>
Нет плагинов
Я думаю, что самый простой способ обойти это без какого-либо плагина - это просто переопределить проверку по умолчанию, например так:
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
var regex = /^(\d*)(\,\d{1,2})?$/; //99999,99
return regex.test(value);
}
</script>
Если вы посмотрите на исходный код jquery.validate.js
вы увидите, что он просто проверяет регулярное выражение, как в приведенном выше коде, плюс проверяет, является ли элемент необязательным:
После некоторых исследований... я нашел решение.
Web.config в <system.web>
добавлять
<globalization culture="auto" uiCulture="auto" enableClientBasedCulture="true"/>
Расширить класс 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 в конце <head>
добавлять
@Html.MetaAcceptLanguage();
<script type="text/javascript">
$(document).ready(function () {
var data = $("meta[name='accept-language']").attr("content");
$.global.preferCulture(data);
});
</script>
После этих изменений я могу манипулировать десятичными числами с помощью моего веб-интерфейса.
С уважением, Джакомо
Я из Аргентины, и я давно борюсь с этой проблемой, мы используем "," в качестве десятичного разделителя, если вы пишете "запятая", проверка Javascript завершается неудачно, но если вы поставите ".", модель получит число, переведенное в целое число (55.60 будет 5560)
Я решил эту проблему с помощью этого простого решения:
Во-первых, я обновил библиотеки проверки jquery, используя новые адреса cdn: http://jqueryvalidation.org/
ссылки, которые я включил в свой JavaScript, это:
<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>
и если вы хотите его на определенном языке (в моем случае на испанском), добавьте также эту строку:
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/localization/messages_es.js"></script>
Замените ES на язык, который вы хотите.
2-й - если вы хотите разрешить десятичную числовую клавиатуру, вы должны заменить "." с "," для правильной работы добавьте этот код на свою страницу, чтобы сделать это автоматически:
$('#txtCurrency').keyup(function () {
$('#txtCurrency').val($('#txtCurrency').val().replace(/\./g, ','));
});
Престо, проблема решена.
До свидания.
Спасибо за эту страницу, избавил меня от многих проблем, мне пришлось как-то исправить код глобализации. Шведская культура не принимает точку в качестве разделителя, но поскольку parseFloat использует базовый javasacript, точки разбора будут приниматься в качестве десятичного разделителя, но на стороне сервера они будут отклонены. Чтобы это исправить, я перезаписываю parseFloat вот так
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);
};
Я открыл билет на их Github, так что, возможно, это будет исправлено