dotnet / AspNetCore.Docs

Documentation for ASP.NET Core
https://docs.microsoft.com/aspnet/core
Creative Commons Attribution 4.0 International
12.62k stars 25.3k forks source link

Show support jQuery validation for non-English locales that use a comma (",") for a decimal point #4076

Open Rick-Anderson opened 7 years ago

Rick-Anderson commented 7 years ago

https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation mentions You may not be able to enter decimal points or commas in the Price field. To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app.

Need tutorial that shows how to do this. Until the tutorial is written, follow these instructions:

On Index.cshtml add

@System.Globalization.CultureInfo.CurrentUICulture

Refreshing the page you should see en-US displayed at the very top. This will help to see if you does have localization enabled on mvc. When localization is working it can be removed.

To enable another locale than default on mvc you need to add localization support (read Globalization and localization in ASP.NET Core)

For this sample, let's just add es-UY locale and set as the default.

on Startup.cs:

app.UseRequestLocalization("en-UY", "fr-FR");

this will add support for locale "es-UY" and also make it the default culture.

refreshing the Index page on your browser should now show es-UY as the current UI locale.

At this point, using decimal points on the client as 19.50 will allow the jQuery validation but on the server it won't be seen as decimals so you will end with 1.950,00 value.

Then you need to use Globalize with jquery-validation-globalize plugin.

See Globalize installation instructions and jquery-validation-globalize installation instructions. Unfortunately those instructions use bower for the installation and the ASP.NET CORE 2.0 and late doesn't use bower. If you want to use the recommended NPM way, you can still do it. Either way, I highly recommend you check out both projects for documentation and more info. You just need to install Globalize with jquery-validation-globalize plugin - how you do it is secondary.

After you managed to install Globalize and jquery-validation-globalize plugin then you need to use it on your html pages.

on _ValidationScriptsPartial.cshtml add the new required javascript files (after jQuery):

<!-- cldr scripts (needed for globalize) -->
<script src="~/lib/cldrjs/dist/cldr.js"></script>
<script src="~/lib/cldrjs/dist/cldr/event.js"></script>
<script src="~/lib/cldrjs/dist/cldr/supplemental.js"></script>

<!-- globalize scripts -->
<script src="~/lib/globalize/dist/globalize.js"></script>
<script src="~/lib/globalize/dist/globalize/number.js"></script>
<script src="~/lib/globalize/dist/globalize/date.js"></script>

<script src="~/lib/jquery-validation-globalize/jquery.validate.globalize.js"></script>

Refresh your page, it should work with the current culture (in this case, es-UY).

The LibMan tool requires VS 15.8.0 Preview 2.0 or later.

Hope it helps. image

rogeriokoski commented 3 years ago

Just an update on the nice solution provided by @XelaNimed as the newly versions of Visual Studio do not use Bower anymore and cldr-data changed to cldr-json. Notice the paths for the json changed as well as the path in localePattern variable:

@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment
@{
    string GetDefaultLocale()
    {
        const string localePattern = "lib\\cldr-json\\cldr-numbers-modern\\main\\{0}";
        var currentCulture = System.Globalization.CultureInfo.CurrentCulture;
        var cultureToUse = "en-US"; //Default regionalisation to use

        if (System.IO.Directory.Exists(System.IO.Path.Combine(HostingEnvironment.WebRootPath, string.Format(localePattern, currentCulture.Name))))
            cultureToUse = currentCulture.Name;
        else if (System.IO.Directory.Exists(System.IO.Path.Combine(HostingEnvironment.WebRootPath, string.Format(localePattern, currentCulture.TwoLetterISOLanguageName))))
            cultureToUse = currentCulture.TwoLetterISOLanguageName;

        return cultureToUse;
    }
}
<script type="text/javascript">
    var culture = "@GetDefaultLocale()";
    $.when(
        $.get("/lib/cldr-json/cldr-core/supplemental/likelySubtags.json"),
        $.get("/lib/cldr-json/cldr-numbers-modern/main/" + culture + "/numbers.json"),
        $.get("/lib/cldr-json/cldr-core/supplemental/numberingSystems.json"),
        $.get("/lib/cldr-json/cldr-dates-modern/main/" + culture + "/ca-gregorian.json"),
        $.get("/lib/cldr-json/cldr-dates-modern/main/" + culture +"/timeZoneNames.json"),
        $.get("/lib/cldr-json/cldr-core/supplemental/timeData.json"),
        $.get("/lib/cldr-json/cldr-core/supplemental/weekData.json")
    ).then(function () {
        // Normalize $.get results, we only need the JSON, not the request statuses.
        return [].slice.apply(arguments, [0]).map(function (result) {
            return result[0];
        });
    }).then(Globalize.load).then(function () {
        Globalize.locale(culture);
    });
</script>
Lesnoj84 commented 2 years ago

This must be a tutorial for beginners, but steps that are written here are more than complicated. I have not a single idea what you need to do. It was clear until author starts to throw all kind of other links at and saying that you need to do this and that click here and there and bla bla bla. Really this isnt much of a help.

ffslight commented 2 years ago

The steps to get globalization to work as suggested here, does not seem to work in Visual Studio 2022.

rafaelrpd commented 2 years ago

Hey guys, how are you all?

If you're getting hard time to solve this globalize install problem, there is how I've solved it to follow properly Razor Pages tutorial.

  1. You need to learn how to use libman, it will help you a lot. Use LibMan with ASP.NET Core in Visual Studio

  2. At solution explorer, add Client-Side Library and install those libraries:

    • From CDNJS provider:
      • globalize

        put it inside wwwroot/lib/globalize/

      • cldrjs

        put it inside wwwroot/lib/cldrjs/

    • From JSDELIVR:
      • jquery-validation-globalize

        put it inside wwwroot/lib/jquery-validation-globalize/

  3. With those libs properly installed, you need to add this lines of code at bottom of /Pages/Shared/__ValidationScriptsPartial.cshtml

    <!-- cldr script (needed for globalize) -->
    <script src="~/lib/cldrjs/cldr.js"></script>
    <!-- globalize script -->
    <script src="~/lib/globalize/globalize.js"></script>
    <!-- jquery validation script with globalize -->
    <script src="~/lib/jquery-validation-globalize/jquery.validate.globalize.js"></script>
  4. ~If you're following the razor pages tutorial all along, you should~ EDIT, all apps put this line of code inside Program.cs. Remember to put it before app.Run();

    app.UseRequestLocalization("YOUR_LOCALIZATION");

    Change YOUR_LOCALIZATION to your real localization, like taught by @Rick-Anderson at first answer. :point_right: First answer

Btw, thank you Rick-Anderson! Much appreciated your help at this matter, it was driving me crazy.

eduarddejong commented 2 years ago

Hi, I am coming from the ASP.NET Razor Pages tutorial as well, te be more precies: https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/validation?view=aspnetcore-6.0&tabs=visual-studio

Even as an experienced developer in many technologies (but not so much modern ASP.NET Core yet - that's why I wanted to follow this tutorial), I experience some issues.

First we have the point that the docs are really a bit messy (for example: things of general relevance only being visible under the "Visual Studio Code" tab) and also really a bit outdated (for example: Part 2 talks about many problems and warnings with null check errors which are all solved issues in the current version).

But let's talk about the specific issue with Globalization/Localization here, because I am trying to get things working as well. I notice issues on multiple aspects:

  1. The first thing someone sees when navigating with the links to this page is someone talking about "Startup.cs". This is not part of the default template in .NET 6 anymore, but refers to older ASP.NET Core projects. Which confuses new people.

  2. A bit of trying with available methods in VS Code reveals to me multiple ways of configuring Localization:

    • builder.Services.AddLocalization()
    • builder.Services.AddRequestLocalization(options => { /* Certain configuration here. */ })
    • app.UseRequestLocalization(), which also has a parameterless version (can we use that and wat does it do?) etc. I miss clarity here. Nobody else seems to talk about the first two from the IServiceCollection that I mentioned here, but maybe we can use those as well or maybe we even need those.
j03ll0b0 commented 2 years ago

Hey guys, how are you all?

If you're getting hard time to solve this globalize install problem, there is how I've solved it to follow properly Razor Pages tutorial.

  1. You need to learn how to use libman, it will help you a lot. Use LibMan with ASP.NET Core in Visual Studio
  2. At solution explorer, add Client-Side Library and install those libraries:

    • From CDNJS provider:

      • globalize

        put it inside wwwroot/lib/globalize/

      • cldrjs

        put it inside wwwroot/lib/cldrjs/

    • From JSDELIVR:

      • jquery-validation-globalize

        put it inside wwwroot/lib/jquery-validation-globalize/

  3. With those libs properly installed, you need to add this lines of code at bottom of /Pages/Shared/__ValidationScriptsPartial.cshtml
<!-- cldr script (needed for globalize) -->
<script src="~/lib/cldrjs/cldr.js"></script>
<!-- globalize script -->
<script src="~/lib/globalize/globalize.js"></script>
<!-- jquery validation script with globalize -->
<script src="~/lib/jquery-validation-globalize/jquery.validate.globalize.js"></script>
  1. If you're following the razor pages tutorial all along, you should put this line of code inside Program.cs. Remember to put it before app.Run();
app.UseRequestLocalization("YOUR_LOCALIZATION");

Change YOUR_LOCALIZATION to your real localization, like taught by @Rick-Anderson at first answer. point_right First answer

Btw, thank you Rick-Anderson! Much appreciated your help at this matter, it was driving me crazy.

my VS Code About page: Versión: 1.72.0 Commit: 64bbfbf67ada9953918d72e1df2f4d8e537d340e Fecha: 2022-10-04T23:20:47.539Z Electrón: 19.0.17 Chromium: 102.0.5005.167 Node.js: 16.14.2 V8: 10.2.154.15-electron.0 OS: Linux x64 5.19.14-xanmod1 En espacio aislado: No I can confirm this solution works just fine, es-VE

dotnet tool install -g Microsoft.Web.LibraryManager.Cli
libman init
libman install globalize
libman install cldrjs
libman install jquery-validation-globalize --provider jsdelivr

then following the rest as described by @rafaelrpd at Here

dannevesdantas commented 1 year ago

@Rick-Anderson does it make sense to write the instructions provided here by @rafaelrpd in the body of the https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation page?

Rick-Anderson commented 1 year ago

@damienbod @Bartmax @hishamco would one of you be able to review the instructions provided here by @rafaelrpd

Rick-Anderson commented 1 year ago

@mkArtakMSFT can you have someone review the instructions provided here by @rafaelrpd

hishamco commented 1 year ago

@rafaelrpd @Rick-Anderson could you please let me know what this script is doing? This is the first time I see it

BTW this is one of the oldest issues in localizations, it mainly related to jQuery if I'm not wrong

damienbod commented 1 year ago

LGTM maybe an integrity check is needed if including the js file from a CDN

dannevesdantas commented 1 year ago

I remember the instructions provided by @rafaelrpd for using globalize.js is quite similar to the instructions in the old Getting Started with ASP.NET MVC 4/5 pages at here and here from 2013/2014. The globalize.js GitHub project's page is https://github.com/globalizejs/globalize and it’s also available from npm and bower. It’s a very popular project on GitHub btw.

dannevesdantas commented 1 year ago

Looks like it’s also possible to adapt and update the text and instructions provided in the old "Getting Started with ASP.NET MVC 4/5" tutorials from here and here to the current .NET version, with no major changes.

hishamco commented 1 year ago

We need to check ..

dannevesdantas commented 1 year ago

@Rick-Anderson @hishamco it also solves https://github.com/dotnet/AspNetCore.Docs/issues/8585

hishamco commented 1 year ago

Franlky I didn't try before, also never heard about it :)

@Rick-Anderson again I see the issue related to jQuery, the question is what's the issue from localization APIs?

garbiru commented 1 year ago

The solution from @rafaelrpd works fine, but the problem is, it only works for server-side validations, the client-side stopped working.

Is there any solution to this?

Skleni commented 1 year ago

The solution from @rafaelrpd works fine, but the problem is, it only works for server-side validations, the client-side stopped working.

Is there any solution to this?

@garbiru Did you find a solution?

fomoshlo3 commented 1 year ago

I may have read over it. But what's the solution now?

And where i can find better tutorials for asp.net than on learn.microsoft? I mean i see you try to solve this and have propably put much work into it, but this isn't the first 'Tutorial' from learn.microsoft that feels like loss-of-time due to inconsequent documentation and confusion by mentioning solutions for older versions of that whole framework thinggy.

onetoucheddy commented 1 year ago

Folowing code worked in VS 2017 ASP.NET application Framework 4.5

using Microsoft.AspNet.Localization; using System.Web.Mvc;

public partial class Startup
{
    public class LanguageActionFilter : ActionFilterAttribute
    {
        private readonly ILogger _logger;

        public LanguageActionFilter(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger("LanguageActionFilter");
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            string culture = context.RouteData.Values["culture"].ToString();
            _logger.LogInformation($"Setting the culture from the URL: {culture}");

if NET451

        System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
        System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

elif NET46

        System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
        System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

else

        //    CultureInfo.CurrentCulture = new CultureInfo(culture);
        //    CultureInfo.CurrentUICulture = new CultureInfo(culture);

endif

            base.OnActionExecuting(context);
        }
    }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLocalization(options => options.ResourcesPath = "Resources");

        services.AddScoped<LanguageActionFilter>();

        services.Configure<RequestLocalizationOptions>(
            options =>
            {
                var supportedCultures = new List<CultureInfo>
                    {
                        new CultureInfo("en-US"),
                        new CultureInfo("de-CH"),
                        new CultureInfo("fr-CH"),
                        new CultureInfo("it-CH"),
                        new CultureInfo("nl"),
                        new CultureInfo("en-AU"),
                        new CultureInfo("en-GB"),
                        new CultureInfo("en"),
                        new CultureInfo("es-ES"),
                        new CultureInfo("es-MX"),
                        new CultureInfo("es"),
                        new CultureInfo("fr-FR"),
                        new CultureInfo("fr-BE")
                                    };

                options.SupportedCultures = supportedCultures;
                options.SupportedUICultures = supportedCultures;
            });
    }

How to make this work in ASP.NET core 7.0 in VS 2022? The docs and implementations I found so far are not working or incomplete. After 40 years of programming, there is still no easy way to implement a decimal comma instead of a point? I must be missing something.

christian0712 commented 1 year ago

TUVE EL MISMO PROBLEMA Y LO SOLUCIONE EN 2 PASOS! Gracias a ChatGPT

  1. Solo agregas en wwroot/js/validation.js (este archivo y dentro escribes) $.validator.methods.number = function (value, element) { return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:.\d{3})+)(?:,\d+)?$/.test(value); };

  2. Cargas este archivo en Pages/Shared/_ValidationScriptsPartial.cshtml

Y listo funcionando! al 100% pones volver a cargar el proyecto f5 y puedes poner decimales ejemplo: 5,60

onetoucheddy commented 1 year ago

Thanks. Got it.

Cheers,

Eddy

Van: christian0712 @.> Verzonden: maandag 31 juli 2023 19:38 Aan: dotnet/AspNetCore.Docs @.> CC: onetoucheddy @.>; Comment @.> Onderwerp: Re: [dotnet/AspNetCore.Docs] Show support jQuery validation for non-English locales that use a comma (",") for a decimal point (#4076)

TUVE EL MISMO PROBLEMA Y LO SOLUCIONE EN 2 PASOS! Gracias a ChatGPT

  1. Solo agregas en wwroot/js/validation.js (este archivo y dentro escribes) $.validator.methods.number = function (value, element) { return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:.\d{3})+)(?:,\d+)?$/.test(value); };
  2. Cargas este archivo en Pages/Shared/_ValidationScriptsPartial.cshtml

Y listo funcionando! al 100% pones volver a cargar el proyecto f5 y puedes poner decimales ejemplo: 5,60

— Reply to this email directly, view it on GitHub https://github.com/dotnet/AspNetCore.Docs/issues/4076#issuecomment-1658856461 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AZ47GVMNAEGVG5D53MCML6LXS7UPXANCNFSM4DYAI62A . You are receiving this because you commented.Message ID: @.***>

SoumyadipYT-OSS commented 3 months ago

Now you can add jQuery.Validation.Globalize package directly from NuGet package manager form Visual Studio 2022 IDE. Just goto Tools -> NuGet PackageManager -> Manage NuGetPackages for solution

There after click! 'Browse'

Search for Globalize currency.

You'll find Globalize Currency (Latest stable 1.1.0).

Click! Install....

After that check the uncheck box of your ASP.NET core project, click! apply.

pickarooney commented 3 months ago

I've tried everything suggested here and it's still not possible to enter 8,99 as a price with fr-FR locale