jQuery UI DatePicker a lokalizace/globalizace v ASP.NET

Jan Holan       30.09.2013       ASP.NET/IIS, HTTP/HTML, JavaScript       32144 zobrazení

V .NET rozlišujeme lokalizaci a globalizaci:

  • Lokalizace – Zobrazování textů v aplikaci v některém z jazyků (language), do kterého je aplikace přeložena. V .NET nám nastavený jazyk vrací vlastnost System.Globalization.CultureInfo.CurrentUICulture.
  • Globalizace – Nastavení formátování čísel, data, času apod. podle zvyklostí daného národa (region) - kultury. V .NET nám nastavený jazyk vrací vlastnost System.Globalization.CultureInfo.CurrentCulture.

Tyto vlastnosti můžeme podle potřeby a scénáře buď přebírat z nastavení Windows nebo je nechat přímo v aplikaci zvolit uživatelem. Konkrétně v ASP.NET aplikacích můžeme celkem snadno dosáhnout toho, aby bylo toto nastavení převzato z preferencí prohlížeče, nastavením globalization ve web.config souboru:

<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="auto" uiCulture="auto" />

Pokud se pohybujeme v oblasti JavaScriptu a jQuery, existují sice některé řešení globalizace (jako například jQuery Globalization Plugin). Zdá se ale, že se zde tento model lokalizace vs. globalizace úplně vytrácí a neřeší se.

Pří zavádění jQuery UI DatePicker kontrolu do ASP.NET aplikace jsem si místo toho připravil vlastní jednoduchou třídu, která se stará o jeho inicializaci tak, aby respektovala .NET nastavení jak lokalizace CurrentUICulture tak i globalizace CurrentCulture.

image

Začneme HTML kódem DatePicker kontrolu. Do ASP.NET stránky umístíme klasický TextBox, kterému přidáme class datepicker (*):

<asp:TextBox ID="txtDatePicker" runat="server" CssClass="datepicker" />

Podle této třídy bude javascript (jQuery) hledat všechny kontroly, na které zavolá inicializační metodu datepicker z jQuery UI. Tento script bude právě záviset na nastavení lokalizace a globalizace, a proto ho budeme vytvářet C# třídou. Třídu jsem nazval JQueryHelper. Aby tento kód vracející script šel jednoduše (a čistě) vložit do ASP.NET Web forms stránky, umístíme ho do statické metody InitDatePicker vracející typ HtmlString (je to jakási obdoba helpers tříd v ASP.NET MVC).

using System;

namespace System.Web
{
    /// <summary>
    /// HTML jQuery helper
    /// </summary>
    public static class JQueryHelper
    {
        /// <summary>
        /// Convert a .NET date format to jQuery
        /// </summary>
        public static string ConvertDateFormatToJQuery(string format)
        {
            // Date used in this comment : 5th - Nov - 2009 (Thursday)
            // 
            // .NET    JQueryUI        Output      Comment
            // --------------------------------------------------------------
            // d       d               5           day of month(No leading zero)
            // dd      dd              05          day of month(two digit)
            // ddd     D               Thu         day short name
            // dddd    DD              Thursday    day long name
            // M       m               11          month of year(No leading zero)
            // MM      mm              11          month of year(two digit)
            // MMM     M               Nov         month name short
            // MMMM    MM              November    month name long.
            // yy      y               09          Year(two digit)
            // yyyy    yy              2009        Year(four digit)

            string currentFormat = format;

            //Convert the date
            currentFormat = currentFormat.Replace("dddd", "DD");
            currentFormat = currentFormat.Replace("ddd", "D");

            //Convert month
            if (currentFormat.Contains("MMMM"))
            {
                currentFormat = currentFormat.Replace("MMMM", "MM");
            }
            else if (currentFormat.Contains("MMM"))
            {
                currentFormat = currentFormat.Replace("MMM", "M");
            }
            else if (currentFormat.Contains("MM"))
            {
                currentFormat = currentFormat.Replace("MM", "mm");
            }
            else
            {
                currentFormat = currentFormat.Replace("M", "m");
            }

            //Convert year
            currentFormat = currentFormat.Contains("yyyy") ? currentFormat.Replace("yyyy", "yy") : currentFormat.Replace("yy", "y");

            return currentFormat;
        }

        /// <summary>
        /// Returns script to init jQuery DatePicker with localization
        /// </summary>
        public static IHtmlString InitDatePicker()
        {
            //Using CSS class 'datepicker' to identify DatePicker controls

            string dateformat = ConvertDateFormatToJQuery(System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern);

            string html = @"<script type=""text/javascript"">
                                jQuery(function ($) {
                                    if ($.isFunction($('.datepicker').datepicker)) {
                                        $('.datepicker').datepicker({
                                            showOtherMonths: true,
                                            selectOtherMonths: true,
                                            dateFormat: '" + dateformat + @"'
                                        });
                             
                                        $.datepicker.setDefaults($.datepicker.regional['']);  //Restore the default for Localization Fallback
                                        $.datepicker.setDefaults($.datepicker.regional['" + System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName + @"']);
                                    }
                                });
                            </script>";

            return new HtmlString(html);
        }
    }
}

Ve scriptu ve volání inicializace metodou datepicker nastavuji patřičný dateformat. Ten je získán pomocnou C# metodou ConvertDateFormatToJQuery odvozený právě z CurrentCulture (konkrétně CurrentCulture.DateTimeFormat.ShortDatePattern). Dále se pomoci setDefaults nastavují lokalizační hodnoty DataPicker kontrolu pomoci hodnot pole regional. Nejprve se nastaví výchozí lokalizace (pro fallback) a poté teprve ten požadovaný podle CurrentUICulture TwoLetterISOLanguageName.

Všimněte si ještě, že třída je umístěna přímo v namespace System.Web, to nám umožní snadné volání přímo na aspx stránce (typicky master page), které může vypadat například takto:

<!DOCTYPE html>
<html lang="cs">
<head runat="server">
    ...
    <webopt:BundleReference runat="server" Path="~/Content/themes/base/css" />
</head>
<body>
    <form id="form" runat="server">
        <asp:ScriptManager runat="server" AjaxFrameworkMode="Enabled" EnableCdn="true">
            <Scripts>
                ...
                <asp:ScriptReference Name="jquery" />
                <asp:ScriptReference Name="jquery.ui.combined" />
            </Scripts>
        </asp:ScriptManager>
        <%: Scripts.Render("~/bundles/AppJs") %>

        <%: JQueryHelper.InitDatePicker() %>

        ...
    </form>
</body>
</html>

Ve stránce také nesmíme zapomenout inicializovat jQuery UI a CSS pro jeho theme (já zde používám Bundling & minification, o kterém jsme si něco pověděli například zde a zde).

Aby nám uvedené řešení fungovalo, chybí nám poslední část skládačky. Tou je sada lokalizačních scriptů pro DataPicker. Takový script například pro češtinu vypadá takto:

/* Czech initialisation for the jQuery UI date picker plugin. */
jQuery(function($){
	$.datepicker.regional['cs'] = {
		closeText: 'Zavřít',
		prevText: 'Předchozí',
		nextText: 'Další',
		currentText: 'Dnes',
		monthNames: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'],
		monthNamesShort: ['Led', 'Úno', 'Bře', 'Dub', 'Kvě', 'Čer', 'Čvc', 'Srp', 'Zář', 'Říj', 'Lis', 'Pro'],
		dayNames: ['Neděle', 'Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota'],
		dayNamesShort: ['Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So', ],
		dayNamesMin: ['Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'],
		weekHeader: 'Týd',
		dateFormat: 'dd.mm.yy',
		firstDay: 1,
		isRTL: false,
		showMonthAfterYear: false,
		yearSuffix: ''};
	$.datepicker.setDefaults($.datepicker.regional['cs']);
});

Zde je vidět inicializace hodnoty datepicker.regional['cs'] pole regional, kterou pro daný jazyk právě nastavujeme. Tyto lokalizační scripty jsou při stažení jQuery UI k dispozici v podadresáři development-bundle\ui\i18n, a to buď samostatně (jmenují se jquery.ui.datepicker-xx.js), nebo jako jeden spojený script (jquery-ui-i18n.js). Druhou možností je tento script stáhnout a nainstalovat pomoci NuGet balíčku PM> Install-Package jQuery.UI.i18n.

Já jsem potřebné lokalizační scripty umístil do adresáře Scripts\Cultures a zahrnul do bundlu aplikačních scriptů:

bundles.Add(new ScriptBundle("~/bundles/AppJs").Include(
                "~/Scripts/App/*.js",
                "~/Scripts/Cultures/*.js"));

Tím je DatePicker kontrol funkční, ještě můžeme v CSS stylu upravit velikost prvku a font kalendáře:

.datepicker {
    width: 95px !important;
}

.ui-datepicker {
    font-size: 0.8em !important;
}

(*) Druhou variantou než použit CSS class datepicker na rozlišení kontrolů pro DatePicker je použít nový HTML5 input typ date (nebo datetime) (více zde nebo zde): <input type="date" >

Poté provést kontrolu, zda není DatePicker podporován nativně (pomoci Modernizr) a prvek vyhledat selektorem podle typu date:

//Setup datepickers if we don't support it natively!
if (!Modernizr.inputtypes.date) {
    if ($.isFunction($("input[type='date']").datepicker)) {
        $("input[type='date']").datepicker(...);
        ...                             
    }
}

V dnešní době jsou ale tyto HTML5 typy snad kromě emailu stále většinou browserů nepodporované. Podporuje je co vím pouze Chrome a Opera, ani IE11 je stále nepodporuje (přijde vám také jako mě, že IE 11 vůbec nic nového nepřináší Sad smile). S ohledem na tuto skutečnost dávám radši přednost zachování větší kompatibility a používám zatím variantu s CSS třídou datepicker.

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback