Alcuni anni fa ci siamo occupati di come impostare la culture per la validazione client side con jQuery.Validate e, in particolare, Globalize.js. Questo framework nel tempo è stato completamente rivoluzionato, e oggi è interamente basato su CLDR (acronimo di Common Locale Data Repository), un progetto di Unicode Consortium che contiene un enorme numero di regole di localizzazione, non solo per numeri e date, ma anche nomi degli stati, delle lingue, della pluralizzazione, ecc.
Il sito ufficiale di questo progetto è raggiungibile a questo URL: http://cldr.unicode.org/
Come possiamo sfruttare questa enorme mole di dati nella nostra applicazione ASP.NET? Il primo passo è quello di includere i necessari script e il modo più semplice per farlo è aggiungere due package NuGet:
install-package cldrjs install-package jquery-globalize
Questi sono i componenti infrastrutturali, che richiedono però una serie di informazioni addizionali specifiche per le culture che vogliamo supportare. I metadati di CLDR sono implementati sotto forma di file JSON, che vengono combinati tra di loro fino a generare il modello a oggetti vero e proprio. Essi sono disponibili in una serie di repository su GitHub, che possiamo raggiungere a partire da questo indirizzo: https://github.com/unicode-cldr/cldr-json
Come possiamo intuire, si tratta di un gran numero di file, e il rischio di perdersi nei meandri di GitHub è davvero molto alto. Un tool che ci viene in aiuto per capire quali siano quelli che effettivamente dobbiamo includere è questa pagina web, nella quale possiamo selezionare le funzioni che effettivamente vogliamo supportare: http://johnnyreilly.github.io/globalize-so-what-cha-want/
Immaginiamo, per esempio, di voler supportare solo la globalization delle date, il risultato sarà simile a quello dello screenshot in basso e includerà, oltre all'infrastruttura già aggiunta tramite NuGet, alcuni elementi globali nella cartella "supplemental" più altri che variano a seconda della culture.
Questi sono i file che dovremo scaricare da GitHub e aggiungere nella nostra cartella scripts, fino ad avere una struttura simile a quella della figura in basso, nella quale abbiamo aggiunto il supporto alla sola cultura italiana.
Ora che abbiamo aggiunto tutti i file necessari, possiamo creare un nuovo bundle in BundleConfig che comprenda i file JavaScript di cui abbiamo bisogno:
bundles.Add(new ScriptBundle("~/bundles/globalize").Include( "~/Scripts/cldr.js", "~/Scripts/cldr/event.js", "~/Scripts/cldr/supplemental.js", "~/Scripts/globalize.js", "~/Scripts/globalize/number.js", "~/Scripts/globalize/date.js"));
Ora rechiamoci sulla nostra layout view, e carichiamo anche questo nuovo bundle:
@Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/globalize") @RenderSection("scripts", required: false) @if (!this.IsSectionDefined("scripts")) { @Scripts.Render("~/bundles/jqueryval") }
I componenti così caricati non sono ancora idonei ad assolvere il loro compito, perchè non abbiamo associato le definizioni JSON relative alla culture. Pertanto, al caricamento della pagina, dobbiamo ricordarci di effettuare il download dal server delle definizioni necessarie con alcune chiamate AJAX:
<script> @{ var culture = "it"; } $(function () { $.when( $.get('@Url.Content("~/Scripts/cldr/supplemental/likelySubtags.json")') .success(function (data) { Globalize.load(data); }), $.get('@Url.Content($"~/Scripts/cldr/main/{culture}/numbers.json")') .success(function (data) { Globalize.load(data); }), $.get('@Url.Content("~/Scripts/cldr/supplemental/numberingSystems.json")') .success(function (data) { Globalize.load(data); }), $.get('@Url.Content($"~/Scripts/cldr/main/{culture}/ca-gregorian.json")') .success(function (data) { Globalize.load(data); }), $.get('@Url.Content($"~/Scripts/cldr/main/{culture}/timeZoneNames.json")') .success(function (data) { Globalize.load(data); }), $.get('@Url.Content("~/Scripts/cldr/supplemental/timeData.json")') .success(function (data) { Globalize.load(data); }), $.get('@Url.Content("~/Scripts/cldr/supplemental/weekData.json")') .success(function (data) { Globalize.load(data); }) ).then(function () { Globalize.locale('@culture'); }); }) </script>
Nel codice in alto abbiamo prima creato una variabile server side, culture, in questo esempio forzatamente impostata su "it", e poi l'abbiamo sfruttata per generare il path corretto per gli script da caricare. In un sito multilingua, invece, potremo determinare questo dato da Thread.CurrentThread.CurrentUICulture.
Ora che il tutto è configurato, manca un ultimo passaggio, ossia impostare l'uso di Globalize.js nelle funzioni di validazione di jQuery.Validate. Lo script necessario è concettualmente banale (non dobbiamo far altro che impostare i validator per i diversi tipi di dato), ma richiede una certa conoscenza di come jQuery.Validate funzioni internamente. L'alternativa più semplice è replicare lo snippet presente in questo blog post: http://blog.johnnyreilly.com/2015/10/jquery-validation-globalize-hits-10.html
(function ($, Globalize) { if (!$.validator) { return; } // Clone original methods we want to call into var originalMethods = { min: $.validator.methods.min, max: $.validator.methods.max, range: $.validator.methods.range }; // Globalize options - initially just the date format used for parsing // Users can customise this to suit them $.validator.methods.dateGlobalizeOptions = { dateParseFormat: { skeleton: "yMd" } }; // Tell the validator that we want numbers parsed using Globalize $.validator.methods.number = function (value, element) { var val = Globalize.parseNumber(value); return this.optional(element) || ($.isNumeric(val)); }; // Tell the validator that we want dates parsed using Globalize $.validator.methods.date = function (value, element) { var val = Globalize.parseDate(value, $.validator.methods.dateGlobalizeOptions.dateParseFormat); return this.optional(element) || (val instanceof Date); }; // Tell the validator that we want numbers parsed using Globalize, // then call into original implementation with parsed value $.validator.methods.min = function (value, element, param) { var val = Globalize.parseNumber(value); return originalMethods.min.call(this, val, element, param); }; $.validator.methods.max = function (value, element, param) { var val = Globalize.parseNumber(value); return originalMethods.max.call(this, val, element, param); }; $.validator.methods.range = function (value, element, param) { var val = Globalize.parseNumber(value); return originalMethods.range.call(this, val, element, param); }; }(jQuery, Globalize));
Finalmente i passaggi sono terminati! Se abbiamo svolto tutto correttamente, dovremmo essere in grado di validare client side, una data inserita in formato italiano senza alcun ulteriore intervento. Per provarlo ci basta creare una semplice pagina di esempio:
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Ottimizzazione dei block template in Angular 17
Creare una libreria CSS universale: i bottoni
Persistere la ChatHistory di Semantic Kernel in ASP.NET Core Web API per GPT
Eseguire una query su SQL Azure tramite un workflow di GitHub
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Code scanning e advanced security con Azure DevOps
Utilizzare la funzione EF.Parameter per forzare la parametrizzazione di una costante con Entity Framework
Path addizionali per gli asset in ASP.NET Core MVC
Creare un webhook in Azure DevOps
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
Simulare Azure Cosmos DB in locale con Docker
I più letti di oggi
- Simulare Azure Cosmos DB in locale con Docker
- Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- .NET Conference Italia 2024 - Milano
- .NET Conference Italia 2023 - Milano e Online