Dobrovoi Master
сделано с душой
В состоянии постоянного подключения...

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

Обновленная версия простого, но при этом функционального календаря для вывода на страницах вашего сайта или блога.
Данный скрипт, выводит в нужном вам месте, на текущий месяц и выделяет цветом актуальную дату, предоставляя пользователю возможность выбрать год и месяц. Внешний вид календарика, формируется с помощью 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>

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

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

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

Всего комментариев: 6

  • Александр: 25 октября, 2015 в 13:49

    Здравствуйте.
    На календаре не работает кнопка смены года в меньшую сторону.
    И еще вопрос. Каким образом можно на кнопку конкретной даты прикрепить ссылку на конкретную страницу сайта?
    Вообще, можно ли установить такой календарь на своем сайте-блоге с целью использования его для навигации по блогу?
    Заранее благодарю за ответ!

    Ответить
    • driver: 25 октября, 2015 в 23:33

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

      Ответить
  • Александр: 25 октября, 2015 в 17:10

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

    Ответить
  • Александр: 26 октября, 2015 в 01:14

    Ух ты!!! Это как раз то, что мне нужно. Разобрался в коде как прицеплять ссылку к кнопке.
    Но появилась еще одна проблемка. Раскидал весь код по файлам (html, css, js). Но календарь на странице выглядит так:
    imglink.ru/show-image.php…5da4121dd303e04f
    Наверное, что-нибудь, куда-нибудь забыл еще прицепить? Я, вообще-то еще чайник. Только-только начал изучать php.

    Ответить
    • driver: 26 октября, 2015 в 01:58

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

      Ответить
  • Александр: 26 октября, 2015 в 03:24

    Спасибо огромное человеческое, Андрей, за вашу помощь. В интернете, действительно много информации как подключить календарь к блогу, но все это касается уже готовых площадок. Просто для обычного сайта я ничего не смог найти.
    Вставил js в саму страницу html и все начало работать, как вы и сказали.
    Жаль, конечно, что не получается подключить файлом. Не могу понять в чем проблема.
    Вроде бы все перепроверил сто раз. Все файлы созданы. И css и js. Пути тоже правильные прописаны. Но работать никак не хочет))) И большой js-код в html-странице тоже оставлять не хочется.
    В итоге, поменял расширение файла с .js на .php, и подключил полученный php-файл через require_once.
    Кто увидит, засмеют))) Зато все работает)
    И еще, только что определилась еще одна проблема (для моего именно случая). Мне нужна еще и английская версия календаря, а у них неделя начинается с воскресенья. Я могу это сам быстро поменять? Или код сильно должен изменится?
    Мне не удобно так просить. Я бы заплатил вам за помощь разумную цену.

    Ответить

Оставить комментарий

Ваш email не будет опубликован.

Вы можете использовать следующие HTML тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>