Календарь на JavaScript
Для одного из рабочих проектов мне потребовался календарик на JavaScript. Можно было, конечно, поискать что-то готовое, но гораздо приятнее написать собственный вариант. В результате был написан вот такой кроссбраузерный скрипт календаря, который легко дополняется любыми нужными функциями. Например, в рабочем проекте была добавлена проверка, чтобы пользователь не мог выбрать дни и листать месяцы далее определенной даты. Здесь я выкладываю только базовый вариант скрипта без дополнительных наворотов. Код подробно прокомментирован, с его пониманием проблем быть не должно.Code (JavaScript) : Убрать нумерацию
- // Скрипт календарика с возможностью выбора даты
- calendar = {};
- // Названия месяцев
- calendar.monthName=[
- 'Январь', 'Февраль', 'Март', 'Апрель',
- 'Май', 'Июнь', 'Июль', 'Август',
- 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
- ];
- // Названия дней недели
- calendar.dayName=[
- 'ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС'
- ];
- // Выбранная дата
- calendar.selectedDate = {
- 'Day' : null,
- 'Month' : null,
- 'Year' : null
- };
- // ID элемента для размещения календарика
- calendar.element_id=null;
- // Выбор даты
- calendar.selectDate = function(day,month,year) {
- calendar.selectedDate={
- 'Day' : day,
- 'Month' : month,
- 'Year' : year
- };
- calendar.drawCalendar(month,year);
- }
- // Отрисовка календарика на выбранный месяц и год
- calendar.drawCalendar = function(month,year) {
- var tmp='';
- tmp+='<table class="calendar" cellspacing="0" cellpadding="0">';
- // Месяц и навигация
- tmp+='<tr>';
- tmp+='<td class="navigation" '+
- 'onclick="calendar.drawCalendar('+(month>1?(month-1):12)+
- ','+(month>1?year:(year-1))+');">◄<\/td>';
- tmp+='<td colspan="5" class="navigation" '+
- 'onclick="calendar.drawCalendar('+
- calendar.selectedDate.Month+','+
- calendar.selectedDate.Year+');">'+
- calendar.monthName[(month-1)]+' - '+year+'<\/td>';
- tmp+='<td class="navigation" '+
- 'onclick="calendar.drawCalendar('+(month<12?(month+1):1)+
- ','+(month<12?year:(year+1))+');">►<\/td>';
- tmp+='<\/tr>';
- // Шапка таблицы с днями недели
- tmp+='<tr>';
- tmp+='<th>'+calendar.dayName[0]+'<\/th>';
- tmp+='<th>'+calendar.dayName[1]+'<\/th>';
- tmp+='<th>'+calendar.dayName[2]+'<\/th>';
- tmp+='<th>'+calendar.dayName[3]+'<\/th>';
- tmp+='<th>'+calendar.dayName[4]+'<\/th>';
- tmp+='<th class="holiday">'+calendar.dayName[5]+'<\/th>';
- tmp+='<th class="holiday">'+calendar.dayName[6]+'<\/th>';
- tmp+='<\/tr>';
- // Количество дней в месяце
- var total_days = 32 - new Date(year, (month-1), 32).getDate();
- // Начальный день месяца
- var start_day = new Date(year, (month-1), 1).getDay();
- if (start_day==0) { start_day=7; }
- start_day--;
- // Количество ячеек в таблице
- var final_index=Math.ceil((total_days+start_day)/7)*7;
- var day=1;
- var index=0;
- do {
- // Начало строки таблицы
- if (index%7==0) {
- tmp+='<tr>';
- }
- // Пустые ячейки до начала месяца или после окончания
- if ((index<start_day) || (index>=(total_days+start_day))) {
- tmp+='<td class="grayed"> <\/td>';
- }
- else {
- var class_name='';
- // Выбранный день
- if (calendar.selectedDate.Day==day &&
- calendar.selectedDate.Month==month &&
- calendar.selectedDate.Year==year) {
- class_name='selected';
- }
- // Праздничный день
- else if (index%7==6 || index%7==5) {
- class_name='holiday';
- }
- // Ячейка с датой
- tmp+='<td class="'+class_name+'" '+
- 'onclick="calendar.selectDate('+
- day+','+month+','+year+');">'+day+'<\/td>';
- day++;
- }
- // Конец строки таблицы
- if (index%7==6) {
- tmp+='<\/tr>';
- }
- index++;
- }
- while (index<final_index);
- tmp+='<\/table>';
- // Вставить таблицу календарика на страницу
- var el=document.getElementById(calendar.element_id);
- if (el) {
- el.innerHTML=tmp;
- }
- }
Из интересных плюшек хотел бы обратить ваше внимание на код для определения количества дней в месяце. В JavaScript штатных функция для этого нет, но есть вот такой красивый вариант. Рекомендую его запомнить, он может пригодиться и в других проектах.
Code (JavaScript) : Убрать нумерацию
- // year - год
- // month [0..11] - месяц
- total_days = 32 - new Date(year, month, 32).getDate();
- // теперь в total_days количество дней в месяце
Code (HTML) : Убрать нумерацию
- /* Таблица календарика */
- .calendar {
- border: 1px solid #909090;
- border-collapse: collapse;
- font-family: Arial;
- font-size: 14px;
- }
- /* Заголовок */
- .calendar th {
- text-align: center;
- width: 36px;
- height: 36px;
- background: #D0D0D0;
- color: #000000;
- border: 1px solid #909090;
- }
- /* Заголовок праздника */
- .calendar th.holiday {
- color: #FF0000;
- }
- /* Ячейка дня */
- .calendar td {
- text-align: right;
- width: 28px;
- height: 36px;
- padding-right: 8px;
- border: 1px solid #909090;
- text-align: right;
- cursor: pointer;
- }
- /* Затемненный день */
- .calendar td.grayed {
- background: #F0F0F0;
- cursor: auto !important;
- }
- /* Выбранный день */
- .calendar td.selected {
- background: #6DAFBF;
- color: #FFFFFF;
- box-shadow: 1px 1px rgba(255, 255, 255, 0.5) inset;
- }
- /* Праздничный день */
- .calendar td.holiday {
- color: #FF0000;
- }
- /* Кнопки навигации */
- .calendar td.navigation {
- text-align: center;
- border: 0px none !important;
- font-size: 20px;
- cursor: pointer;
- white-space: nowrap;
- }
Code (JavaScript) : Убрать нумерацию
- // ID элемента для размещения календарика
- calendar.element_id = 'calendar_table';
- // По умолчанию используется текущая дата
- calendar.selectedDate={
- 'Day' : new Date().getDate(),
- 'Month' : parseInt(new Date().getMonth(),10)+1,
- 'Year' : new Date().getFullYear()
- };
- // Нарисовать календарик
- calendar.drawCalendar(
- calendar.selectedDate.Month,
- calendar.selectedDate.Year
- );
Просмотров: 18282 | Комментариев: 25
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(15.10.2019 в 15:52):
Через кассу
Мария
(14.10.2019 в 14:09):
Добрый день!
Подскажите, пожалуйста, как прописать в коде чтобы отображался квартал, 3 месяца, а не один.
Заранее благодарю!
Подскажите, пожалуйста, как прописать в коде чтобы отображался квартал, 3 месяца, а не один.
Заранее благодарю!
Любовь
(02.11.2017 в 22:52):
ManHunter, Я уже кучу времени потратила на попытки реализации и перепробовала множество способов. Например :
<input id='MyDate' type='text' readonly>
<script>
var MyDate.value=calendar.selectedDate;
</script>
Или же просто для вывода на экран:
<a onclick="alert(calendar.selectedDate);">
Узнать дату </a>
Можно к вам как то обратиться за помощью?
<input id='MyDate' type='text' readonly>
<script>
var MyDate.value=calendar.selectedDate;
</script>
Или же просто для вывода на экран:
<a onclick="alert(calendar.selectedDate);">
Узнать дату </a>
Можно к вам как то обратиться за помощью?
ManHunter
(02.11.2017 в 20:58):
Вот и присваивай это значение нужному полю ввода или куда там оно требуется.
Любовь
(02.11.2017 в 18:59):
Здравствуйте. Как можно организовать вывод выбранной даты в отдельное поле с помощью calendar.selectDate?
Алексей
(19.04.2017 в 15:45):
Спасибо!
Александр
(23.09.2014 в 18:42):
не подскажешь, почему при клике на календарь, он исчезает, а с инпут все норм? По идеи я догадываюсь зачем, но не подскажешь как сделать?
Александр
(19.09.2014 в 23:34):
Это не то, вот решение этому:
document.onclick = function(ev) {
myDiv = document.getElementById('calendar_table');
myDate = document.getElementById('calendar_date'); //input
if (ev.target.id != myDiv.id && ev.target.id != myDate.id && myDiv.style.display == 'block') {
myDiv.style.display = 'none';
}
}
Также сделал правку в классе...
document.onclick = function(ev) {
myDiv = document.getElementById('calendar_table');
myDate = document.getElementById('calendar_date'); //input
if (ev.target.id != myDiv.id && ev.target.id != myDate.id && myDiv.style.display == 'block') {
myDiv.style.display = 'none';
}
}
Также сделал правку в классе...
ManHunter
(19.09.2014 в 20:39):
onclick на body или другом обрамляющем элементе
Александр
(19.09.2014 в 20:31):
Я имел ввиду после окончания месяца, но я ошибся (для этого просто сделал новую переменную и плюсовал в цикле, а до этого как вы сказали, но еще плюсовал 1). Также я его чуток доработал и сделал кнопки покрасивее. исходник могу скинуть. Я не совсем профи с жаваскрипт, поэтому не могли бы подсказать как сделать событие клика на пустом месте документа(при клике на инпут, он показывается)?
ManHunter
(16.09.2014 в 21:41):
Я бы присвоил index2 значение (количество дней в предыдущем месяце - start_day) а потом внутри цикла его плюсовал. Как-то так.
Александр
(16.09.2014 в 21:33):
else if (index>=(total_days+start_day)) {
index2 = index-total_days+1;
tmp+='<td class="grayed">'+index2+'<\/td>';
}
Вы бы также сделали бы?
Ой, неверно.
index2 = index-total_days+1;
tmp+='<td class="grayed">'+index2+'<\/td>';
}
Вы бы также сделали бы?
Ой, неверно.
ManHunter
(16.09.2014 в 21:16):
Совершенно верно.
Александр
(16.09.2014 в 21:11):
Я так понял надо сделать соответствующий код сюда if (index<start_day) {} и сюда else if (index>=(total_days+start_day)) {} ?
ManHunter
(16.09.2014 в 21:03):
Я почти всегда в курсе, что происходит на сайте )
Александр
(16.09.2014 в 20:59):
ManHunter, спасибо. Попробую сейчас реализовать. Не ожидал, что так быстро ответите
ManHunter
(16.09.2014 в 20:48):
Посчитать по аналогии прошлый месяц, заполнить первые ячейки. Следующий месяц от 1 числа до конца последних пустых ячеек.
Александр
(16.09.2014 в 20:43):
Как сделать чтобы в пустых ячейках были даты прошлого и будущего месяца?
ManHunter
(01.04.2014 в 12:12):
Лабораторные работы делаются за деньги. Не можешь делать сам - платишь тем, кто может.
Сергей
(01.04.2014 в 12:11):
Я понимаю что я задаю глупые вопросы, с программирование на 3 максимум)) но это надо попытаться реализовать)
Еще у меня такой вопрос
хотелось бы добавить сверху возможность смены года (ну и соответственно чтобы месяца перерисовывал в соответствии с годом)
Можете подсказать как это реализовать с вашим кодом? ))
Заранее спасибо)
Еще у меня такой вопрос
хотелось бы добавить сверху возможность смены года (ну и соответственно чтобы месяца перерисовывал в соответствии с годом)
Можете подсказать как это реализовать с вашим кодом? ))
Заранее спасибо)
ManHunter
(01.04.2014 в 07:16):
// Количество ячеек в таблице
var final_index=сколько надо
Может найти себе другое занятие, если в коде с подробными комментариями возникают такие вопросы?
var final_index=сколько надо
Может найти себе другое занятие, если в коде с подробными комментариями возникают такие вопросы?
Сергей
(01.04.2014 в 01:38):
Возник другой вопрос))
как сделать, чтобы для чисел кол-во ячеек всегда было 6 (чтобы месяца ровно отображались, а то у кого то 5 строчек для чисел, а у другого 6, и получается криво) ?
Заранее большое спасибо)
как сделать, чтобы для чисел кол-во ячеек всегда было 6 (чтобы месяца ровно отображались, а то у кого то 5 строчек для чисел, а у другого 6, и получается криво) ?
Заранее большое спасибо)
Сергей
(31.03.2014 в 23:48):
Спасибо))
ManHunter
(31.03.2014 в 23:40):
Разметка года таблицей, ячейки от id="month_1" до "month_12"
В цикле
calendar.element_id='month_'+i
...
'Month' : i
В основном коде убрать навигацию. Все.
В цикле
calendar.element_id='month_'+i
...
'Month' : i
В основном коде убрать навигацию. Все.
Сергей
(31.03.2014 в 23:31):
У меня вот такой вопрос.
Я хочу чтобы был не один месяц на странице а сразу год целиком.
Хотел сделать это через цикл for и указанием в html data-m="0" (и так для всех месяцев)
Как перебрать этот код (навигацию в месяце уберу), чтобы не писать новый, чтобы он год целиком?
Я хочу чтобы был не один месяц на странице а сразу год целиком.
Хотел сделать это через цикл for и указанием в html data-m="0" (и так для всех месяцев)
Как перебрать этот код (навигацию в месяце уберу), чтобы не писать новый, чтобы он год целиком?
Добавить комментарий
Заполните форму для добавления комментария