Перейти к содержимому

Как сделать календарь html

  • автор:

Календарь

Выбор даты применяется на сайтах, торгующих авиа и железнодорожными билетами, ведь посетителя интересует заказ билета на определённый день. Календари также применяются в блогах, где записи систематизируются по дате, и сайтах, связанных с разными событиями, например, спортивными. Так или иначе, календарь востребован и может быть добавлен следующим образом.

На сервер данные передаются в формате ГГГГ-ММ-ДД, например, 22.12.2014, а вид календаря может различаться в зависимости от браузера. Полностью поддерживает календарь пока только Opera, выводя виджет для выбора любой даты (рис. 1).

Календарь в браузере Opera

Рис. 1. Календарь в браузере Opera

Браузер Chrome также поддерживает календарь, но делает это весьма скупо (рис. 2). По сути вы только можете прокручивать дату или вводить её как текст.

Календарь в Chrome

Рис. 2. Календарь в Chrome

В примере 1 показано создание календаря для выбора произвольной даты.

Пример 1. Календарь

HTML5 IE Cr Op Sa Fx

    Календарь   

Выберите дату:

Допустимо ограничить ввод даты заданным значением через атрибуты min и max , они соответственно указывают нижнюю и верхнюю дату. Так, если вам требуется сузить диапазон ввода до ±3 дней от даты 01.06.2012, то код запишется, как показано в примере 2.

Пример 2. Ограничение даты

HTML5 IE Cr Op Sa Fx

    Календарь   

Выберите дату:

Текущая дата заданная через атрибут value подсвечивается фоном, неактивные дни, которые нельзя выбрать — серым цветом (рис. 3).

Календарь с диапазоном ввода

Рис. 3. Календарь с диапазоном ввода

Кроме традиционного календаря, в котором можно выбрать дату, месяц и год, существует и календарь только для ввода месяца и недели. Они записываются в таком виде.

Выбор месяца в Opera происходит через аналогичный виджет, но в этом случае нельзя указать конкретную дату (рис. 4).

Выбор месяца в Opera

Рис. 4. Выбор месяца в Opera

На сервер данные поля type=»month» пересылаются как ГГГГ-ММ, например, 2014-10.

Похожим образом выглядит и виджет для выбора недели (рис. 5), но дополнительно выводится номер недели и выбрать можно только её. На сервер при этом значение отправляется как 2014-W38, где вначале указывается год, затем через дефис W и после него номер недели от начала года.

Выбор недели в Opera

Рис. 5. Выбор недели в Opera

В примере 3 показано создание поля для ввода месяца.

Пример 3. Выбор месяца

HTML5 IE Cr Op Sa Fx

    Календарь   

Укажите месяц:

doctor Brain

При создании различных веб-сервисов работа с датами и временем практически всегда занимает весомое место. Создание календаря — достаточно простая задача, которая, тем не менее, часто вызывает затруднения в реализации у начинающих разработчиков.

Сегодня мы создадим виджет простого месячного календаря, отвечающий следующим условиям:

  1. по умолчанию загружается текущий месяц,
  2. текущая дата выделяется,
  3. возможно смещение по календарю на месяц вперед или назад.

HTML

Создадим контейнер обертку month-calendar, в котором разместим три блока:

  1. month: содержит наименования месяца и года, а также элементы навигации,
  2. weekdays: наименования дней недели,
  3. days: собственно, сам календарь (табличная часть, содержит дни месяца).

Так выглядит html-разметка основных блоков календаря:

Обратите внимание: несмотря на визуальную реализацию виджета в виде таблицы, для каждого из вышеперечисленных дочерних элементов контейнера month-calendar мы используем немаркированный список ul . Соответственно, в дальнейшем мы будем манипулировать элементами списков li .

А вот и финальная верстка:

В данном случае для элементов навигации нужно подключить библиотеку Font Awesome (Web Font или SVG версию).

CSS

В основе позиционирования элементов календаря находится модель flexbox.

* < box-sizing: border-box; >body < font-family: sans-serif; >/* месяцы и годы */ #month-calendar < width: 100%; >.month < margin: 0; padding: 3rem 2rem 2rem; background: #555555; text-align: center; width: 100%; color: #ffffff; list-style: none; >.month li < padding: 0; margin: 0; font-size: 1.5rem; line-height: 1.4; letter-spacing: 0.1rem; text-transform: uppercase; font-weight: 700; >.month li.prev, .month li.next < cursor: pointer; >.month li.prev < float: left; >.month li.next < float: right; >.month li.year-name < font-size: 1.2rem; font-weight: 400; >/* дни недели */ .weekdays < margin: 0; padding: 1rem 0; background-color: #dddddd; width: 100%; display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: left; >.weekdays li < display: inline-block; flex: 0 0 calc(100% / 7); text-align: center; >/* дни */ .days < margin: 0; padding: 1rem 0; background-color: #eeeeee; width: 100%; display: flex; flex-wrap: wrap; justify-content: left; align-content: flex-start; height: 14rem; >.days li < padding: 0.5rem; list-style: none; display: inline-block; flex: 0 0 calc(100% / 7); text-align: center; color: #999; font-size: 0.9rem; line-height: 1rem; >.days li.date-now

На что обратить внимание:

  1. ширина контейнера month-calendar равна 100%: width: 100% ,
  2. для элементов навигации prev и next используются свойства float: left и float-right ,
  3. блок days имеет фиксированную высоту height: 14rem , что позволяет избежать смещения или наложения элементов при динамической смене данных виджета,
  4. для табличной части календаря элементы li располагаются слева направо и сверху вниз: горизонтальное выравнивание — justify-content: left , вертикальное — align-content: flex-start ,
  5. в одном ряду табличной части находится семь элементов, это достигается за счет использования выражения calc: flex: 0 0 calc(100% / 7) ,
  6. для исключения влияния размеров отсутпов на расчетные значения для всех элементов установлено свойство box-sizing: border-box .

JS

Основу работы виджета составляют свойства и методы встроенного объекта Date.

Экземпляр объекта Date

создать новый экземпляр объекта Date можно только через конструктор:

let nowDate = new Date(); // создаем экземпляра объекта с текущей датой let curDate = new Date(year,month,day); // создаем экземпляр объекта для определенной календарной даты; 

Вызов Date() как функции (без new) вернет не экземпляр объекта, а строку.

Как получить год, месяц, дату?

Чтобы получить год, месяц, дату экземпляра объетка Date, обратимся к встроенным методам:

nowDate.getFullYear(); // возвращает год в четырехзначном формате nowDate.getMonth(); // возвращает номер месяца (значение от 0 до 11. Январь равен 0) nowDate.getDate(); // возвращает текущую дату 
Как получить название месяца?

Чтобы получить назавние месяца воспользуемся массивом:

let arrMonthName = ['январь','февраль','март','апрель','май','июнь','июль','август','сентябрь','октябрь','ноябрь','декабрь']; let monthName = arrMonthName[NowDate.getMonth()]; // получаем название месяца 
Как получить текущий день недели?

Для определения текущего дня недели тоже существует встроенная функция:

nowDate.getDay() // возвращает номер дня недели 

Обратие внимание: отсчет дней недели идет с воскресенья, которое равно 0.

Как получить количество дней в месяце?

Существует небольшая хитрость, основанная на способности методов объекта Date автоматически пересчитывать параметры, приводя их к корректному значению. Так, если мы установим дату экземпляра объекта равной 0, метод getDate() вернет дату последнего дня предыдущего месяца, то есть полученное значение будет равнятся количеству дней в предыдущем месяце:

monthDays = new Date(year, month + 1, 0).getDate(); // возвращает количество дней в выбранном месяце 
Как получить количество дней недели до начала текущего месяца.

Если неделя стартует с воскресенья, для определения количества дней недели до начала текущего месяца достаточно получить номер первого дня текущего месяца:

new Date(year,month,1).getDay() // возвращает номер дня недели 

В случае, когда неделя начинается с понедельника, нужно получит номер последнего дня недели предыдущего месяца:

new Date(year,month,0).getDay() // возвращает номер дня недели 
Как корректно сместить дату на месяц назад или вперед?

Мы опять обращаемся к способности методов объекта Date автоматически корректировать дату:

curDate.setMonth(curDate.getMonth() + 1); // смещает дату на месяц вперед curDate.setMonth(curDate.getMonth() - 1); // смещает дату на месяц назад 
Итоговый JS-файл

Опираясь на данные, полученные выше создадим итоговый код JavaScript:

Результат

А вот и пример на codepen:

Спасибо за внимание.

Новые публикации

Photo by CHUTTERSNAP on Unsplash

JavaScript: сохраняем страницу в pdf

Photo by David Everett Strickler on Unsplash

2021-07-12

HTML: Полезные примеры

Photo by Pankaj Patel on Unsplash

2021-07-11

CSS: Ускоряем загрузку страницы

Photo by Evan Fitzer on Unsplash

2021-07-10

JavaScript: 5 странностей

Photo by Markus Spiske on Unsplash

2021-07-10

JavaScript: конструктор сортировщиков

Категории

О нас

Frontend & Backend. Статьи, обзоры, заметки, код, уроки.

© 2021 dr.Brain .
мир глазами веб-разработчика

Календарь с помощью CSS-grid в несколько строк кода

Сетка календаря выглядит, как идеальный кандидат для использования CSS-grid. Ниже рассмотрим пример, как можно сделать разметку для календарика с помощью всего нескольких строк кода. В итоге должно получиться так:

Calendar layout based on CSS-grid

Начать следует с HTML-разметки:

 
Mo
Su
1
31

В нормальных условиях обычно не приходится вручную писать все числа

1. 31

. Эта часть легко может быть сгенерирована с помощью Javascript в браузере или сервером, поэтому для примера будет использоваться только HTML и CSS.

В разметке будут две части: контейнер для дней недели .days-of-week-container и контейнер для чисел месяца .calendar-container . Оба будут реализованы с помощью CSS-grid, а текст будет выравниваться по правому краю:

.days-of-week-container, .calendar-container

Теперь, если посмотреть на сетку, станет ясно, что здесь будет 7 колонок, поэтому первое, что приходит в голову, написать как-то вроде:

grid-template-columns: 30px 30px 30px 30px 30px 30px 30px;

Но это слишком примитивно и некрасиво, поэтому для настройки наших колонок будем использовать repeat :

grid-template-columns: repeat(7, 30px);

Теперь, дни недели и сам календарь на месяц будут располагаться в макете сетки, состоящей из 7 колонок.

Что делать, если месяц должен начинаться не в понедельник, а например, в пятницу? Достаточно использовать CSS-свойство grid-column и переместить первый день месяца в колонку любого дня недели в календаре, а автоматическое размещение позаботится обо всем остальном.

.calendar-container div:first-child

Для установки значения grid-column можно использовать настраиваемые CSS-свойства и управлять расположением первого дня месяца из Javascript. Как это сделать, можно посмотреть на странице о передаче данных между CSS и JavaScript с помощью CSS-переменных.

Это всё, что требуется для реализации простого макета календаря: CSS-grid и всего несколько строк кода.

Календарь-1 для сайта на JavaScript

Простой календарь для сайта на CSS и JavaScript.
Представленный календарь предназначен для просмотра ближайших дней плюс-минус месяц. Календарь можно листать до нужного года как вперед, так и назад.

Вид календаря на странеце сайта

  1. Разместить все три части на одной странице.
  2. Разместить часть 1 (стиль календаря) в отдельном файле.css.
  3. Разместить часть 3 (скрипт календаря) в отдельном файле.js и подключить к странице сайта.
1. Стиль календаря
 .look-calendar < width:220px; border:1px solid #c0c0c0; padding:6px; margin: 0 auto; >#calendar < width: 100%; line-height: 1.2em; font-size: 15px; text-align: center; border-spacing:0px; >#calendar tr.dn td < font-size: 15px; >#calendar thead tr:last-child < font-size: small; color: #555555; >#calendar thead tr:nth-child(1) td:nth-child(2) < color: #323232; >#calendar thead tr:nth-child(1) td:nth-child(1):hover, #calendar thead tr:nth-child(1) td:nth-child(3):hover < cursor: pointer; >#calendar tbody td < color: #2c567a; >#calendar tbody td:nth-child(n+6), #calendar .holiday < color: #e78c5c; >#calendar tbody td.today
2. Код календаря на страние сайта.html
 
ПнВтСрЧтПтСбВс
3. Скрипт календаря

function calendar(id, year, month) < var Dlast = new Date(year, month + 1, 0).getDate(), D = new Date(year, month, Dlast), DNlast = new Date(D.getFullYear(), D.getMonth(), Dlast).getDay(), DNfirst = new Date(D.getFullYear(), D.getMonth(), 1).getDay(), calendar = '', month = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"]; if (DNfirst != 0) < for (var i = 1; i < DNfirst; i++) calendar += ''; > else < for (var i = 0; i < 6; i++) calendar += ''; > for (var i = 1; i ‘ + i; > else < calendar += '' + i; > if (new Date(D.getFullYear(), D.getMonth(), i).getDay() == 0) < calendar += ''; > > for (var i = DNlast; i < 7; i++) calendar += ''; document.querySelector('#' + id + ' tbody').innerHTML = calendar; document.querySelector('#' + id + ' thead td:nth-child(2)').innerHTML = month[D.getMonth()] + ' ' + D.getFullYear(); document.querySelector('#' + id + ' thead td:nth-child(2)').dataset.month = D.getMonth(); document.querySelector('#' + id + ' thead td:nth-child(2)').dataset.year = D.getFullYear(); if (document.querySelectorAll('#' + id + ' tbody tr').length < 6) < // чтобы при перелистывании месяцев не "подпрыгивала" вся страница, добавляется ряд пустых клеток. Итог: всегда 6 строк для цифр document.querySelector('#' + id + ' tbody').innerHTML += ' '; > > calendar(«calendar», new Date().getFullYear(), new Date().getMonth()); // переключатель минус месяц document.querySelector(‘#calendar thead tr:nth-child(1) td:nth-child(1)’).onclick = function() < calendar("calendar", document.querySelector('#calendar thead td:nth-child(2)').dataset.year, parseFloat(document.querySelector('#calendar thead td:nth-child(2)').dataset.month) - 1); >// переключатель плюс месяц document.querySelector(‘#calendar thead tr:nth-child(1) td:nth-child(3)’).onclick = function() < calendar("calendar", document.querySelector('#calendar thead td:nth-child(2)').dataset.year, parseFloat(document.querySelector('#calendar thead td:nth-child(2)').dataset.month) + 1); >

Для этого календаря Примеры оформления (меняем только CSS).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *