Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
В веб-приложениях нередко приходится сталкиваться с датами. Например, у нас в проекте есть такая модель 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>