I am trying to use the MVC unobstrusive validation with jquery globalize plugin in MVC5 (in conjunction with the package jquery-validate-globalize). For learning purposes I started a demo project as per here, but it fails to run with globalize (it works on default Microsoft unobstrusive validation). The model is very simple:
public class GlobalizeModel
{
[Range(10.5D, 20.3D)]
public decimal Double { get; set; }
[Required]
public DateTime? DateTime { get; set; }
}
I try to initiate Globalize as follows at the bottom of the _Layout page (the view is minimal with 2 input only): (I get list of necessary files from /)
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<!--cldr scripts-->
<script src="~/Scripts/cldr.js"></script>
<script src="~/Scripts/cldr/event.js"></script>
<script src="~/Scripts/cldr/supplemental.js"></script>
<!--globalize scripts-->
<script src="~/Scripts/globalize.js"></script>
<script src="~/Scripts/globalize/number.js"></script>
<script src="~/Scripts/globalize/date.js"></script>
<!--jquery globalize-->
<script src="~/Scripts/jquery.validate.globalize.js"></script>
<script>
$.when(
$.getJSON("/Scripts/cldr/supplemental/likelySubtags.json"),
$.getJSON("/Scripts/cldr/main/en/numbers.json"),
$.getJSON("/Scripts/cldr/supplemental/numberingSystems.json"),
$.getJSON("/Scripts/cldr/main/en/ca-gregorian.json"),
$.getJSON("/Scripts/cldr/main/en/timeZoneNames.json"),
$.getJSON("/Scripts/cldr/supplemental/timeData.json"),
$.getJSON("/Scripts/cldr/supplemental/weekData.json"),
$.getJSON("/Scripts/cldr/main/tr/numbers.json"),
$.getJSON("/Scripts/cldr/main/tr/ca-gregorian.json"),
$.getJSON("/Scripts/cldr/main/tr/timeZoneNames.json"),
console.log("JSONs loaded")
).then(function () {
console.log("start slicing");
return [].slice.apply(arguments, [0]).map(function (result) {
console.log("slicing done");
return result[0];
});
}).then(Globalize.load).then(function () {
Globalize.locale("en");
console.log("Locale set to en");
}).then(console.log("LOADED EVERYTHING"));
</script>
But when I run the page, I only see the console logs JSOns loaded
and LOADED EVERYTHING
. Moreover, when I try a client side validation by typing anything in the number textbox (and of course when the focus is lost), I get the following error in the console:
Uncaught Error: E_DEFAULT_LOCALE_NOT_DEFINED: Default locale has not been defined.
This post here is similar, and I tried to check the things listed there. I think my JSON objects are not fetched, but I am not good aj JS so I am not sure on that. I added the following items to web.config to see if this is something related with file serving, with no avail:
<system.webServer>
<staticContent>
<remove fileExtension=".json"/>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
The culture is set to auto in web.config as follows:
<system.web>
<globalization culture="auto" uiCulture="auto" />
<pilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
</system.web>
You can see Scripts
folder structure in here:
So, what is the problem here? How can I make this thing work?
I am trying to use the MVC unobstrusive validation with jquery globalize plugin in MVC5 (in conjunction with the package jquery-validate-globalize). For learning purposes I started a demo project as per here, but it fails to run with globalize (it works on default Microsoft unobstrusive validation). The model is very simple:
public class GlobalizeModel
{
[Range(10.5D, 20.3D)]
public decimal Double { get; set; }
[Required]
public DateTime? DateTime { get; set; }
}
I try to initiate Globalize as follows at the bottom of the _Layout page (the view is minimal with 2 input only): (I get list of necessary files from https://johnnyreilly.github.io/globalize-so-what-cha-want/)
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<!--cldr scripts-->
<script src="~/Scripts/cldr.js"></script>
<script src="~/Scripts/cldr/event.js"></script>
<script src="~/Scripts/cldr/supplemental.js"></script>
<!--globalize scripts-->
<script src="~/Scripts/globalize.js"></script>
<script src="~/Scripts/globalize/number.js"></script>
<script src="~/Scripts/globalize/date.js"></script>
<!--jquery globalize-->
<script src="~/Scripts/jquery.validate.globalize.js"></script>
<script>
$.when(
$.getJSON("/Scripts/cldr/supplemental/likelySubtags.json"),
$.getJSON("/Scripts/cldr/main/en/numbers.json"),
$.getJSON("/Scripts/cldr/supplemental/numberingSystems.json"),
$.getJSON("/Scripts/cldr/main/en/ca-gregorian.json"),
$.getJSON("/Scripts/cldr/main/en/timeZoneNames.json"),
$.getJSON("/Scripts/cldr/supplemental/timeData.json"),
$.getJSON("/Scripts/cldr/supplemental/weekData.json"),
$.getJSON("/Scripts/cldr/main/tr/numbers.json"),
$.getJSON("/Scripts/cldr/main/tr/ca-gregorian.json"),
$.getJSON("/Scripts/cldr/main/tr/timeZoneNames.json"),
console.log("JSONs loaded")
).then(function () {
console.log("start slicing");
return [].slice.apply(arguments, [0]).map(function (result) {
console.log("slicing done");
return result[0];
});
}).then(Globalize.load).then(function () {
Globalize.locale("en");
console.log("Locale set to en");
}).then(console.log("LOADED EVERYTHING"));
</script>
But when I run the page, I only see the console logs JSOns loaded
and LOADED EVERYTHING
. Moreover, when I try a client side validation by typing anything in the number textbox (and of course when the focus is lost), I get the following error in the console:
Uncaught Error: E_DEFAULT_LOCALE_NOT_DEFINED: Default locale has not been defined.
This post here is similar, and I tried to check the things listed there. I think my JSON objects are not fetched, but I am not good aj JS so I am not sure on that. I added the following items to web.config to see if this is something related with file serving, with no avail:
<system.webServer>
<staticContent>
<remove fileExtension=".json"/>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
The culture is set to auto in web.config as follows:
<system.web>
<globalization culture="auto" uiCulture="auto" />
<pilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
</system.web>
You can see Scripts
folder structure in here:
So, what is the problem here? How can I make this thing work?
Share Improve this question asked Mar 8, 2016 at 9:41 mcymcy 1,2686 gold badges26 silver badges40 bronze badges 2- Did you ever find out what was happening? I think console.log("JSONs loaded") is interfering with the slicing function. – Francisco Commented Aug 2, 2016 at 19:46
-
2
No; I was not able to solve it so I decided to not to use
globalize
. In the actual project, I disabled client side validation and relied on server validation in culture sensitive views (for example ones including decimal input). The reason behind this decision was I spent too much time on this with no avail, and there were a lot of things waiting to be done. Maybe I will revisit this issue in the future hoping globalization technology advances in the meantime. P.S. The problem persisted withoutconsole.log("JSONs loaded")
. – mcy Commented Aug 3, 2016 at 8:48
1 Answer
Reset to default 5I recently ran into the same problem, trying to add I18n to an MVC5 web app. After several days of research and partly using your code as base, I found some things that helped me implement it.
My Solution: In a separate project, I added decimal and DateTime properties to the ApplicationUser class:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public DateTime birthdate { get; set; }
public decimal balance { get; set; }
}
I also modified the RegisterViewModel to accept those properties, as follows:
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[DataType(DataType.DateTime)]
public DateTime birthdate { get; set; }
[Required]
[DataType(DataType.Currency)]
public decimal balance { get; set; }
}
Then, I set the culture in a base controller, from which other controllers inherit:
public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
string[] cultures = { "es-CL", "es-GT", "en-US" };
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultures[1]);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
return base.BeginExecuteCore(callback, state);
}
}
That's just for testing purposes, not the way I fetch culture in the real app.
My file structure is the same as yours and I didn't modify the web.config file.
I also used this link for dependencies. But then I modified a few things in the scripts section of Register.cshtml:
<!-- CLDR -->
<script src="~/Scripts/cldr.js"></script>
<script src="~/Scripts/cldr/event.js"></script>
<script src="~/Scripts/cldr/supplemental.js"></script>
<!-- Globalize -->
<script src="~/Scripts/globalize.js"></script>
<script src="~/Scripts/globalize/number.js"></script>
<script src="~/Scripts/globalize/date.js"></script>
<!-- $ validate -->
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.globalize.js"></script>
<!-- fetch files -->
<script>
$.when(
$.getJSON("/Scripts/cldr/supplemental/likelySubtags.json"),
$.getJSON("/Scripts/cldr/main/en/numbers.json"),
$.getJSON("/Scripts/cldr/supplemental/numberingSystems.json"),
$.getJSON("/Scripts/cldr/main/en/ca-gregorian.json"),
$.getJSON("/Scripts/cldr/main/en/timeZoneNames.json"),
$.getJSON("/Scripts/cldr/supplemental/timeData.json"),
$.getJSON("/Scripts/cldr/supplemental/weekData.json"),
$.getJSON("/Scripts/cldr/main/tr/numbers.json"),
$.getJSON("/Scripts/cldr/main/tr/ca-gregorian.json"),
$.getJSON("/Scripts/cldr/main/tr/timeZoneNames.json"),
).then(function () {
console.log("start slicing");
return [].slice.apply(arguments, [0]).map(function (result) {
console.log("slicing done");
return result[0];
});
}).then(Globalize.load).then(function () {
Globalize.locale("en");
console.log("Locale set to en");
}).then(console.log("LOADED EVERYTHING"));
</script>
The _Layout view scripts weren't modified at all, and I had no problem with the console logs.
That's all, it worked out for me, and as it's a very similar case, I hope it works for you too.