Problem z dziesiętnymi, przecinkami i walidacją po stronie klienta
Próbuję uzyskać walidację po stronie klienta dla anullable<decimal>
którego separatorem dziesiętnym może być przecinek (np .: 123,45).
Według mnie:
...
<div class="editor-label">
@Html.LabelFor(model => model.Turnover)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Turnover)
@Html.ValidationMessageFor(model => model.Turnover)
</div>
...
@section Scripts {
@Styles.Render("~/Content/themes/base/css")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryui")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/jQueryFixes")
...scripts for this view...
}
Moje jQueryFixes zastępujejquery.validate.js
plik dlarange()
inumber()
:
$.validator.methods.range = function (value, element, param) {
var globalizedValue = value.replace(",", ".");
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}
$.validator.methods.number = function (value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
}
... jak zasugerowano w wielu postach / pytaniach dotyczących tego problemu (np .:tutaj lubtutaj).
O dziwo:
Kiedy próbuję przesłać wartość taką jak 123,45 i mimo że debugowałem skrypt za pomocą Firebug i zobaczyłem, że moje nadpisane funkcje są wywoływane i zwracane są prawdą, nie mogę przesłać formularza. Zamiast tego mój EditorFor dla wartości dziesiętnej jest skupiony z dowolnego powodu i nie mogę się dowiedzieć dlaczego.
(Uważam, że moja walidacja po stronie serwera - przy użyciu niestandardowego segregatora itp. - działa dobrze i totu nie ma problemu: Chciałbym uzyskać pomoc dotyczącą sposobu przesyłania formularza lub wyjaśnienia, dlaczego pole wejściowe jest skoncentrowane, nawet jeśli wygląda na poprawne.)
EDYTUJ 1:
Dodatkowe informacje. W moim BundlesConfig.cs:
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
...
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
"~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
bundles.Add(new ScriptBundle("~/bundles/jQueryFixes").Include(
"~/Scripts/jQueryFixes.js"));
...
EDYCJA 2:
Po sugestii @LeftyX próbowałem użyć skryptu Globalize (po usunięciu jQueryFixes.js):
<script type="text/javascript">
...
$( document ).ready(function() {
Globalize.culture("en-US", "pt-PT");
});
$.validator.methods.number = function (value, element) {
return this.optional(element) || jQuery.isNumeric(Globalize.parseFloat(value));
}
//Fix the range to use globalized methods
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
var val = Globalize.parseFloat(value);
return this.optional(element) || (val >= param[0] && val <= param[1]);
}
});
...
</script>
... ale wciąż mam ten sam problem:validator.methods.number
powraca prawda, ale formularz nie jest przesyłany, a zamiast tego pole wejściowe jest skupione.
Jeśli sprawdzę element wejściowy podczas przesyłania, widzę, że szybko z niego wychodziclass="valid"
doclass='input-validation-error'
a potem z powrotem dovalid
. Bardzo dziwny.
WNIOSEK:
@LeftyX dał bardzo dobre i kompletne rozwiązanie dla każdego, kto znajdzie te same problemy.
Miałem już spoiwo niestandardowego modelu dla wartości dziesiętnych dopuszczających wartość zerową, ale skrypt globalizacji, w tym kultura w Modelu / ViewModelu, z pewnością się przyda.
Innym powodem mojego problemu może być fakt, że (przypadkowo) włączałem kilka skryptów dwukrotnie.
UPDATE (lip / 2015):
globalize.js jest teraz trochę inny. Nr ref. dota odpowiedź idokumentacja dla zaktualizowanych kroków.