Главная » Javascript » Обновление скрипта календаря для вашего сайта

Обновление скрипта календаря для вашего сайта

Обновленная версия простого, но при этом функционального календаря для вывода на страницах вашего сайта или блога.
Данный скрипт, выводит в нужном вам месте, на текущий месяц и выделяет цветом актуальную дату, предоставляя пользователю возможность выбрать год и месяц. Внешний вид календарика, формируется с помощью CSS, каждому элементу присвоен cвой определённый класс, так что подогнать под общий дизайн проекта, не составит особого труда.
 
Javascript - Календарь для сайта
 
Для начала, как всегда, посмотрите живой пример работы скрипта:

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

  • Вынести код скрипта в отдельный файл, обозвав его, что-то вроде calendart.js, а затем уже подключить к документу, разместив в районе тега </head> или закрывающего тега </body> следующее:
<script src="ваш-сайт/папка js/calendart.js"></script>
  • Так же, можете разместить код скрипта непосредственно в теле страницы, всё там же, в районе тега </head> или закрывающего тега </body> размещаете следующую конструкцию:

Javascript

<script type="text/javascript">
<!-- 
if (!fcp)
	var fcp = new Object();
if (!fcp.msg)
	fcp.msg = new Object();
if (!fcp)
	var fcp = new Object();
if (!fcp.msg)
	fcp.msg = new Object();
fcp.week_days = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"];
fcp.months = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь",
	"Июль", "Август", "сентябрь", "Октябрь", "Ноябрь", "Декабрь"];
fcp.msg.prev_year = "предыдущий год";
fcp.msg.prev_month = "предыдущий месяц";
fcp.msg.next_month = "следующий месяц";
fcp.msg.next_year = "следующий год";
fcp.Calendar = function(element, show_clock) {
if (!element.childNodes)
throw "HTML element expected";
this.element = element;
this.selection = new Date();
this.show_clock = show_clock;
this.selected_cell = undefined;
this.generate_month();
this.render_calendar();
}
fcp.Calendar.prototype.set_date_time = function (date_time) {
	if (date_time.constructor == Date) {
		this.selection = date_time;
		this.generate_month();
		this.render_calendar();
	} else {
		throw "Date object expected (in fcp.Calendar.set_date_time)";
	}
}
fcp.Calendar.prototype.next_month = function () {
	var month = this.selection.getMonth();
	if (month == 11) {
		this.selection.setMonth(0);
		this.selection.setYear(this.selection.getFullYear() + 1);
	} else {
		this.selection.setMonth(month + 1);
	}
	this.generate_month();
	this.render_calendar();
}
fcp.Calendar.prototype.prev_month = function () {
	var month = this.selection.getMonth();
	if (month == 0) {
		this.selection.setMonth(11);
		this.selection.setYear(this.selection.getFullYear() - 1);
	} else {
		this.selection.setMonth(month - 1);
	}
	this.generate_month();
	this.render_calendar();
}
fcp.Calendar.prototype.next_year = function () {
	var is_feb29 = (this.selection.getMonth() == 1)
		&& (this.selection.getDate() == 29);
	if (is_feb29) {
		this.selection.setDate(1);
		this.selection.setMonth(2); // March
	}
	this.selection.setFullYear(this.selection.getFullYear() + 1);
	this.generate_month();
	this.render_calendar();
}
fcp.Calendar.prototype.prev_year = function () {
	var is_feb29 = (this.selection.getMonth() == 1)
		&& (this.selection.getDate() == 29);
	if (is_feb29) {
		this.selection.setDate(1);
		this.selection.setMonth(2); // March
	}
	this.selection.setFullYear(this.selection.getFullYear() - 1);
	this.generate_month();
	this.render_calendar();
}
fcp.Calendar.prototype.generate_month = function () {
	this.raw_data = new Array();
	var week = 0;
	this.raw_data[week] = new Array(7);
	var first_of_month = fcp.Calendar.clone_date(this.selection);
	first_of_month.setDate(1);
	var first_weekday = first_of_month.getDay();
	first_weekday = (first_weekday == 0) ? 6 : first_weekday - 1;
	for (var i = 0; i < first_weekday; i++) {
		this.raw_data[week][i] = 0;
	}
	var last_of_month = fcp.Calendar.days_in_month(
		this.selection.getYear(),
		this.selection.getMonth());
	var weekday = first_weekday;
	for (var i = 1; i <= last_of_month; i++) {
		this.raw_data[week][weekday] = i;
		weekday++;
		if (weekday > 6) {
			weekday = 0;
			week++;
			this.raw_data[week] = new Array(7);
		}
	}
	for (var i = weekday; i < 7; i++) {
		this.raw_data[week][i] = 0;
	}
}
fcp.Calendar.prototype.render_calendar = function () {
	this.element.selected_cell = undefined;
	this.element.innerHTML = "";
	this.element.appendChild(this.render_month());
}
fcp.Calendar.prototype.render_heading = function () {
	var heading = document.createElement("caption");
	var prev_year = document.createElement("a");
	prev_year.href = "#";
	prev_year.calendar = this;
	prev_year.onclick = function() {
		this.calendar.prev_year();
		return false;
	};
	prev_year.innerHTML = "<<";
	prev_year.title = fcp.msg.prev_year;
	var prev_month = document.createElement("a");
	prev_month.href = "#";
	prev_month.calendar = this;
	prev_month.onclick = function() {
		this.calendar.prev_month();
		return false;
	};
	prev_month.innerHTML = "<";
	prev_month.title = fcp.msg.prev_month;
	var month_year = document.createTextNode(
		"\u00a0" + fcp.months[this.selection.getMonth()]
		+ " " + this.selection.getFullYear() + "\u00a0");
	var next_month = document.createElement("a");
	next_month.href = "#";
	next_month.calendar = this;
	next_month.onclick = function() {
		this.calendar.next_month();
		return false;
	};
	next_month.innerHTML = ">";
	next_month.title = fcp.msg.next_month;
	var next_year = document.createElement("a");
	next_year.href = "#";
	next_year.calendar = this;
	next_year.onclick = function() {
		this.calendar.next_year();
		return false;
	};
	next_year.innerHTML = ">>";
	next_year.title = fcp.msg.next_year;
	heading.appendChild(prev_year);
	heading.appendChild(document.createTextNode("\u00a0"));
	heading.appendChild(prev_month);
	heading.appendChild(month_year);
	heading.appendChild(next_month);
	heading.appendChild(document.createTextNode("\u00a0"));
	heading.appendChild(next_year);
	return heading;
}
fcp.Calendar.prototype.render_month = function() {
	var html_month = document.createElement("table");
	html_month.className = "calendar";
	html_month.appendChild(this.render_heading());
	var thead = document.createElement("thead");
	var tr = document.createElement("tr");
	for (var i = 0; i < fcp.week_days.length; i++) {
		var th = document.createElement("th");
		th.innerHTML =  fcp.week_days[i];
		tr.appendChild(th);
	}
	thead.appendChild(tr);
	html_month.appendChild(thead);
	var tbody = document.createElement("tbody");
	for (var i = 0; i < this.raw_data.length; i++) {
		tbody.appendChild(this.render_week(this.raw_data[i]));
	}
	html_month.appendChild(tbody);
	return html_month;
}
fcp.Calendar.prototype.render_week = function (day_numbers) {
	var html_week = document.createElement("tr");
	html_week.align = "right";
	for (var i = 0; i < 7; i++) {
		html_week.appendChild(this.render_day(day_numbers[i]));
	}
	return html_week;
}
fcp.Calendar.prototype.render_day = function (day_number) {
	var td = document.createElement("td");
	if (day_number >= 1 && day_number <= 31) {
		var anchor = document.createElement("a");
		anchor.href = "#";
		anchor.innerHTML = day_number;
		anchor.calendar = this;
		anchor.date = day_number;
		anchor.onclick = fcp.Calendar.handle_select;
		td.appendChild(anchor);
		if (day_number == this.selection.getDate()) {
			this.selected_cell = td;
			td.className = "in_month selected";
		} else {
			td.className = "in_month";
		}
	}
	return td;
}
fcp.Calendar.prototype.onselect = function () {}
fcp.Calendar.clone_date = function (date_obj) {
	if (date_obj.constructor != Date)
		throw "Date object expected (in fcp.Calendar.clone_date)";
	else
		return new Date(
			date_obj.getFullYear(),
			date_obj.getMonth(),
			date_obj.getDate(),
			date_obj.getHours(),
			date_obj.getMinutes(),
			date_obj.getSeconds());
}
fcp.Calendar.days_in_month = function (year, month) {
	if (month < 0 || month > 11)
		throw "Month must be between 0 and 11";
	var day_count = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	if (month != 1) {
		return day_count[month];
	} else if ((year % 4) != 0) {
		return 28;
	} else if ((year % 400) == 0) {
		return 29;
	} else if ((year % 100) == 0) {
		return 28;
	} else {
		return 29;
	}
}
fcp.Calendar.handle_select = function () {
	if (this.calendar.selected_cell)
	this.calendar.selected_cell.className = "in_month";
	this.calendar.selected_cell = this.parentNode;
	this.parentNode.className = "in_month selected";
	this.calendar.selection.setDate(this.date);
	this.calendar.onselect(this.calendar.selection);
	return false;
}
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}
addLoadEvent(function() {
  cal = new fcp.Calendar(document.getElementById("cal_placeholder"));
  cal.onselect = function(date) {alert(date);}; } )
 // -->
</script>

Как видим, исполняемый код javascript, получился довольно объемный, разобраться интуитивно, что, куда и зачем, будет проблематично, так что метод «тыка» отставьте в сторону, а возникнут вопросы, пишите в комментариях, обязательно отвечу.

Оба варианта подключения скрипта и примеры страниц, вы найдёте в архиве с исходниками, а пока, едем дальше.

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

CSS

/* Базовые стили таблицы календаря */
table.calendar {
    width:200px;
    margin: 0 auto;
    border: 1px solid #ababab;
    background: #f4f4f4;  
    text-align: center;
    font-family: Verdana, Arial, Helvetica, sans-serif;
    font-weight: normal; 
    font-size: 12px;
    padding: 3px;
}
/* Панель сетки календаря */
td.in_month {
    text-align: center; 
    font-weight: normal; 
    font-size: 12px; 
    border: 1px solid #bababa;
    border-radius: 2px;
    -webkit-border-radius: 2px;/*Safari, Chrome*/
    -moz-border-radius: 2px;/*Firefox*/
    background: #ddd;
    background: -moz-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* FF3.6+ */
    background: -webkit-gradient(linear, 90deg, color-stop(0, BFBFBF), color-stop(100%, F6F0EA));/* Chrome,Safari4+ */
    background: -webkit-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* Opera 11.10+ */
    background: -ms-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* IE10+ */   
} 
/* Панель выбора месяца и года */      
table.calendar caption {
    border: 1px solid #ababab;    
    border-bottom: none;
    font-size: 14px;
    font-weight: bold;
    height: 28px;
    line-height: 2.2; 
    text-shadow: 0 1px 1px #fff;
    background: -moz-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* FF3.6+ */
    background: -webkit-gradient(linear, 90deg, color-stop(0, BFBFBF), color-stop(100%, F6F0EA));/* Chrome,Safari4+ */
    background: -webkit-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* Opera 11.10+ */
    background: -ms-linear-gradient(90deg, #BFBFBF 0, #F6F0EA 100%);/* IE10+ */
}
/* Дни недели */       
table.calendar th{
    color: green;
}
/* Выделенная дата */
table.calendar td.selected { 
    background: #00c400; 
    background: -moz-linear-gradient(270deg, #16B831 0, #42FF94 100%);/* FF3.6+ */
    background: -webkit-gradient(linear, 270deg, color-stop(0, 16B831), color-stop(100%, 42FF94));/* Chrome,Safari4+ */
    background: -webkit-linear-gradient(270deg, #16B831 0, #42FF94 100%);/* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(270deg, #16B831 0, #42FF94 100%);/* Opera 11.10+ */
    background: -ms-linear-gradient(270deg, #16B831 0, #42FF94 100%);/* IE10+ */
    font-weight: normal; 
    font-size: 10px; 
}
/* Ссылки сетки дат календаря */
table.calendar a {
    display: block; 
    font-weight: bold; 
    text-decoration: none; 
    color: #4e4ead;  
    text-align: center; 
    font-size: 10px; 
}
/* Ссылки навигации календаря */
table.calendar caption a {
    display: inline;
    font-weight: bold;
    font-size: 10px;
    color: #898989;
    text-shadow: 0 1px 1px #fff;
}

Всё! Теперь остаётся дело за малым, что бы календарь появился у вас на сайте, достаточно там где по вашему разумению и видению ему самое место, расположить маленький div-контейнер, связанный через идентификатор id="cal_placeholder" c javascript:

Html

<div id="cal_placeholder"></div>

Сегодня мы рассмотрели, один из самых простых способов, создания функционального календаря, конечно не самый навороченный, без особых изысков и эффектов, но надёжное и рабочее решение, ничего больше.
Исходники с примерами, упакованы в архив и доступны для скачивания с моего Яндекс.Диска:

С Уважением, Андрей .

Буду признателен, если поделитесь ссылкой на запись в своих соц-сетях:

Google Bookmarks News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Вы можете оставить отзыв, подписаться на обновленияОбновления блога по RSSRSS или Обновления блога на TwitterTwitter !

6 комментариев
  1. Александр:

    Здравствуйте.

    На календаре не работает кнопка смены года в меньшую сторону.

    И еще вопрос. Каким образом можно на кнопку конкретной даты прикрепить ссылку на конкретную страницу сайта?

    Вообще, можно ли установить такой календарь на своем сайте-блоге с целью использования его для навигации по блогу?

    Заранее благодарю за ответ!

    Ответить
    • driver:

      Здравствуйте, Александр.

      В демо всё работает нормально. Обнаружил небольшую ошибку в архиве, исправил и перезалил, можете скачать заново.

      Использовать именно этот календарь для навигации по блогу не получится, в инете достаточно готовых решений по типу календарей для статей используемых в различных CMS.

      Ну, а как привязать ссылку к конкретной дате, можете посмотреть здесь Скрипт немного другой, с оформлением не стал особо заморачиваться, но сам принцип действия, думаю будет вам понятен.

      Ответить
  2. Александр:

    ... или, может быть, можно при нажатии кнопки, возвращать значение переменной в формате ггммдд?

    Ответить
  3. Александр:

    Ух ты!!! Это как раз то, что мне нужно. Разобрался в коде как прицеплять ссылку к кнопке.

    Но появилась еще одна проблемка. Раскидал весь код по файлам (html, css, js). Но календарь на странице выглядит так:

    imglink.ru/show-image.php...5da4121dd303e04f

    Наверное, что-нибудь, куда-нибудь забыл еще прицепить? Я, вообще-то еще чайник. Только-только начал изучать php.

    Ответить
    • driver:

      У вас отображается часть сформированная в html, сам js не срабатывает, поэтому не отображаются элементы календаря, год, месяц и даты. В первую очередь обратите внимание на подключение js, в конце концов пропишите его напрямую в html. Если вы используете скрипт в теле страницы, не забывайте про теги <script type="text/javascript"> </script> внутри которых и следует прописывать исполняемый код (функции) js.

      Ответить
  4. Александр:

    Спасибо огромное человеческое, Андрей, за вашу помощь. В интернете, действительно много информации как подключить календарь к блогу, но все это касается уже готовых площадок. Просто для обычного сайта я ничего не смог найти.

    Вставил js в саму страницу html и все начало работать, как вы и сказали.

    Жаль, конечно, что не получается подключить файлом. Не могу понять в чем проблема.

    Вроде бы все перепроверил сто раз. Все файлы созданы. И css и js. Пути тоже правильные прописаны. Но работать никак не хочет))) И большой js-код в html-странице тоже оставлять не хочется.

    В итоге, поменял расширение файла с .js на .php, и подключил полученный php-файл через require_once.

    Кто увидит, засмеют))) Зато все работает)

    И еще, только что определилась еще одна проблема (для моего именно случая). Мне нужна еще и английская версия календаря, а у них неделя начинается с воскресенья. Я могу это сам быстро поменять? Или код сильно должен изменится?

    Мне не удобно так просить. Я бы заплатил вам за помощь разумную цену.

    Ответить
Присоединяйтесь к обсуждению!

Отправляя кoммeнтapий, Вы автоматически принимаете правила кoммeнтиpoвaния на этом блоге.

Правила кoммeнтиpoвaния на блоге Dobrovoimaster:

  1. Во избежание захламления спамом, первый кoммeнтapий всегда проходит премодерацию.
  2. В поле "Ваш сайт" лучше указывать ссылку на главную страницу вашего сайта/блога. Ссылки на прочую веб-лабуду (в том числе блоги/сплоги, созданные не для людей) будут удалены.
  3. Не используйте в качестве имени комментатора слоганы/названия сайтов, рекламные фразы, ключевые и т.п. слова. В случае несоблюдения этого условия, имя изменяю на свое усмотрение. Просьба указывать нормальное имя или ник.
  4. Скорее всего, что не информативный и короткий кoммeнтapий вида "Спасибо!", "Интересная статья", будет удален. Исключение составляют знакомые автору блога комментаторы.
  5. Комментарии не по теме безжалостно удаляются.

Подписаться не комментируя

Обновления комментариев по RSS RSS комментариев к этой записи »
Рейтинг@Mail.ru