Использование Datepicker jQuery

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 1.11.2015

В веб-приложениях нередко приходится сталкиваться с датами. Например, у нас в проекте есть такая модель Person:

public class Person
{
    public int Id { get; set; }

    [Display(Name = "Имя")]
    public string Name { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd'/'MM'/'yyyy}", ApplyFormatInEditMode = true)]
    [Display(Name = "Дата рождения")]
    public DateTime BirthDate { get; set; }

    [Display(Name = "Страна")]
    public string State { get; set; }
}

Она имеет поля: Id, имя, страна и дата рождения. Все просто, но теперь создадим представление для создания объекта этой модели. Допустим, у нас будет простенький контроллер:

public class PersonsController : Controller
{
    PersonContext db = new PersonContext();

    public ActionResult Index()
    {
        return View(db.Persons);
    }
    [HttpGet]
    public ActionResult Create()
    {
        return View();
    }
    [HttpPost]
    public ActionResult Create(Person person)
    {
        if (ModelState.IsValid)
        {
            db.Persons.Add(person);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(person);
    }
}

И само представление Create.cshtml, в котором и будет происходить создание объекта:

@model DatepickerMvc.Models.Person

@{
    ViewBag.Title = "Create";
}

<h2>Новый пользователь</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Пользователь</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.BirthDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.BirthDate)
            @Html.ValidationMessageFor(model => model.BirthDate)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.State)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.State)
            @Html.ValidationMessageFor(model => model.State)
        </div>

        <p>
            <input type="submit" value="Добавить" />
        </p>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Если мы запустим в Опере 12 или в Хроме, то браузер создаст нам поле для ввода даты в виде календарика, с помощью которого довольно удобно выбирать дату. Например, в Хроме это выглядит так:

Вроде неплохо, но IE или Firefox, например, создадут для ввода даты обычное текстовое поле, а не что-то типа календаря. И тут нам на помощь приходит виджет jquery-ui datepicker.

Этот виджет определен в библиотеке jquery ui. В проектах Basic и Internet Application эта библиотека уже по умолчанию имеется в папке Script и добавлена в бандл jqueryui. Если вы в качестве типа проекта используете шаблон Empty, то надо будет дополнительно подключить соответствующие библиотеки, например, с помощью NuGet.

Итак, чтобы добавить datepicker в приложение, нам надо подключить библиотеку jquery-ui и сопутствующие файлы стилей. Я это сделаю в мастер-странице _Layout.cshtml:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    <!--стили jquery ui-->
    @Styles.Render("~/Content/themes/base/css")
    <!--сама библиотека jquey ui-->
    @Scripts.Render("~/bundles/jqueryui")
    @RenderSection("scripts", required: false)
    <!--если браузер не создает специального поля для date, то добавляем datepicker-->
    <script type="text/javascript">
        $(function () {
            if (!Modernizr.inputtypes.date) {
                $(function () {
                    $("input[type='date']")
                                .datepicker({ dateFormat: 'dd/mm/yy' })
                                .get(0).setAttribute("type", "text");
                })
            }
        });
    </script>
</body>
</html>

Сначала подключаем бандлы скриптов и стилей jquery-ui, которые у нас объявлены в файле BundleConfig.cs в папке App_Start (стили - @Styles.Render("~/Content/themes/base/css") и скрипты - @Scripts.Render("~/bundles/jqueryui")).

После этого, с помощью дополнительного скрипта, используя ранее подключенную библиотеку modernizr, мы проверяем, создает ли браузер специальное поле по типу календарика. Если нет, то добавляем в разметку datepicker.

Обратите внимание на формат даты в datepicker: dateFormat: 'dd/mm/yy'. Этот формат должен совпадать с форматом даты, который содержит данное поле модели, то есть в данном случае DataFormatString = "{0:dd'/'MM'/'yyyy}".

И, обратившись к представлению, например, в браузере Firefox, вы сможете увидеть, что он использует элемент datepicker для выбора дат:

Тут у нас остается только одна проблема, все надписи и календарь на английском. Чтобы руссифицировать, изменим вышеопределенную функцию в коде javascript следующим образом:

<!--если браузер не создает специального поля для date, то добавляем datepicker-->
<script type="text/javascript">
    $(function () {
        if (!Modernizr.inputtypes.date) {
            $(function () {
                $("input[type='date']")
                    .datepicker({ dateFormat: 'dd/mm/yy' })
                    .get(0).setAttribute("type", "text");
                });
                $.datepicker.regional['ru'] = {
                    closeText: 'Закрыть',
                    prevText: 'Пред',
                    nextText: 'След',
                    currentText: 'Сегодня',
                    monthNames: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь',
                    'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
                    monthNamesShort: ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн',
                    'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'],
                    dayNames: ['воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота'],
                    dayNamesShort: ['вск', 'пнд', 'втр', 'срд', 'чтв', 'птн', 'сбт'],
                    dayNamesMin: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
                    weekHeader: 'Не',
                    dateFormat: 'dd.mm.yy',
                    firstDay: 1,
                    isRTL: false,
                    showMonthAfterYear: false,
                    yearSuffix: ''
				};
         $.datepicker.setDefaults($.datepicker.regional['ru']);

        }
    });
</script>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850