Календарь на PHP и Ajax

Календарь на PHP и Ajax

20 сентября 2019 PHP

Пример календаря на PHP и Ajax с переключением месяцев. Можно использовать как заготовку для решения любых задач. Я использовал его для создания плагина календаря мероприятий на WordPress.

Скрипт использует процедурный подход, но имеет разделенную структуру с шаблоном , что довольно удобно. JMS University

Структура файлов календаря

Файл /index.php

<?php

// Получить текущий год, месяц и день
list($iNowYear, $iNowMonth, $iNowDay) = explode('-', date('Y-m-d'));

// Получить текущий год и месяц в зависимости от возможных GET параметров
if (isset($_GET['month'])) {
    list($iMonth, $iYear) = explode('-', $_GET['month']);
    $iMonth = (int)$iMonth;
    $iYear = (int)$iYear;
} else {
    list($iMonth, $iYear) = explode('-', date('n-Y'));
}

// Получить название и количество дней указанного месяца
$iTimestamp = mktime(0, 0, 0, $iMonth, $iNowDay, $iYear);
list($sMonthName, $iDaysInMonth) = explode('-', date('F-t', $iTimestamp));

// Получить предыдущий год и месяц
$iPrevYear = $iYear;
$iPrevMonth = $iMonth - 1;
if ($iPrevMonth <= 0) {
    $iPrevYear--;
    $iPrevMonth = 12; // для декабря
}

// Получить следующий год и месяц
$iNextYear = $iYear;
$iNextMonth = $iMonth + 1;
if ($iNextMonth > 12) {
    $iNextYear++;
    $iNextMonth = 1;
}

// Получить количество дней предыдущего месяца
$iPrevDaysInMonth = (int)date('t', mktime(0, 0, 0, $iPrevMonth, $iNowDay, $iPrevYear));

// Получить числовое представление дня недели первого дня указанного (текущего) месяца
$iFirstDayDow = (int)date('w', mktime(0, 0, 0, $iMonth, 1, $iYear));

// В какой день начинается предыдущий месяц
$iPrevShowFrom = $iPrevDaysInMonth - $iFirstDayDow + 1;

// Если в предыдущем месяце
$bPreviousMonth = ($iFirstDayDow > 0);

// Начальный день
$iCurrentDay = ($bPreviousMonth) ? $iPrevShowFrom : 1;

$bNextMonth = false;
$sCalTblRows = '';

// Генерация строк для календаря
for ($i = 0; $i < 6; $i++) { // 6-недельный диапазон
    $sCalTblRows .= '<tr>';
    for ($j = 0; $j < 7; $j++) { // 7 дней в неделю

        $sClass = '';
        if ($iNowYear == $iYear && $iNowMonth == $iMonth && $iNowDay == $iCurrentDay && !$bPreviousMonth && !$bNextMonth) {
            $sClass = 'today';
        } elseif (!$bPreviousMonth && !$bNextMonth) {
            $sClass = 'current';
        }
        $sCalTblRows .= '<td class="'.$sClass.'"><a href="javascript: void(0)">'.$iCurrentDay.'</a></td>';

        // Следующий день
        $iCurrentDay++;
        if ($bPreviousMonth && $iCurrentDay > $iPrevDaysInMonth) {
            $bPreviousMonth = false;
            $iCurrentDay = 1;
        }
        if (!$bPreviousMonth && !$bNextMonth && $iCurrentDay > $iDaysInMonth) {
            $bNextMonth = true;
            $iCurrentDay = 1;
        }
    }
    $sCalTblRows .= '</tr>';
}

// Подготовка замены ключей и генерация календаря
$aKeys = array(
    '__prev_month__' => "{$iPrevMonth}-{$iPrevYear}",
    '__next_month__' => "{$iNextMonth}-{$iNextYear}",
    '__cal_caption__' => $sMonthName . ', ' . $iYear,
    '__cal_rows__' => $sCalTblRows,
);
$sCalendarItself = strtr(file_get_contents('templates/calendar.html'), $aKeys);

// AJAX-запрос возвращающий календарь
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && isset($_GET['month'])) {
    header('Content-Type: text/html; charset=utf-8');
    echo $sCalendarItself;
    exit;
}

$aVariables = array(
    '__calendar__' => $sCalendarItself,
);
echo strtr(file_get_contents('templates/index.html'), $aVariables);

Файл /templates/index.html

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="utf-8" />
    <meta name="author" content="Script Tutorials" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <title>Календарь на PHP и AJAX</title>

    <!-- скрипты и стили -->
    <link href="css/styles.css" rel="stylesheet" type="text/css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<body>
    <header>
        <h2>Календарь на PHP и AJAX</h2>
    </header>

    <div id="calendar">
        __calendar__
    </div>
</body>
</html>

Файл /templates/calendar.html

<div class="navigation">
    <a class="prev" href="index.php?month=__prev_month__" onclick="$('#calendar').load('index.php?month=__prev_month__&_r=' + Math.random()); return false;"></a>
    <div class="title" >__cal_caption__</div>
    <a class="next" href="index.php?month=__next_month__" onclick="$('#calendar').load('index.php?month=__next_month__&_r=' + Math.random()); return false;"></a>
</div>

<table>
    <tr>
        <th class="weekday">вс</th>
        <th class="weekday">пн</th>
        <th class="weekday">вт</th>
        <th class="weekday">ср</th>
        <th class="weekday">чт</th>
        <th class="weekday">пт</th>
        <th class="weekday">сб</th>
    </tr>
    __cal_rows__
</table>

Файл /css/styles.css

* {
    margin: 0;
    padding: 0;
}
body {
    background-color: #fff;
}
header {
    background-color:rgba(33, 33, 33, 0.9);
    color:#fff;
    display:block;
    font: 14px/1.3 Arial,sans-serif;
    margin-bottom: 10px;
    position:relative;
}
header h2{
    font-size: 22px;
    margin: 0px auto;
    padding: 10px 0;
    width: 80%;
    text-align: center;
}
header a, a:visited {
    text-decoration:none;
    color:#fcfcfc;
}

/* стили календаря */
#calendar {
    -moz-user-select: none;
    border: 1px solid #EEEEEE;
    border-radius: 6px 6px 6px 6px;
    color: #333333;
    font-family: Arial,sans-serif;
    font-size: 1.1em;
    margin: 10px auto;
    padding: 0.4em;
    width: 90%;
}
#calendar .navigation {
    background-color: #565455;
    border: 1px solid #c7c7c7;
    border-radius: 6px 6px 6px 6px;
    color: #FFFFFF;
    font-weight: bold;
    padding: 1px;
    position: relative;
}
#calendar .navigation .title {
    background: none repeat scroll 0 0 transparent;
    border-color: rgba(0, 0, 0, 0);
    color: inherit;
    line-height: 1.8em;
    margin: 0 2.3em;
    text-align: center;
}
#calendar .navigation .prev, #calendar .navigation .next {
    background-image: url(../images/nav.png);
    height: 24px;
    opacity: 0.9;
    position: absolute;
    top: 4px;
    width: 24px;
}
#calendar .navigation .prev {
    background-position: 0 0;
    left: 4px;
}
#calendar .navigation .next {
    background-position: -24px 0;
    right: 4px;
}
#calendar .navigation .prev:hover, #calendar .navigation .next:hover {
    opacity: 1;
}
#calendar table {
    border-collapse: collapse;
    font-size: 0.9em;
    table-layout: fixed;
    width: 100%;
}
#calendar table th {
    border: 0 none;
    font-weight: bold;
    padding: 0.7em 0.3em;
    text-align: center;
}
#calendar table td {
    border: 0 none;
    padding: 1px;
}
#calendar table td a {
    background-color: #EEEEEE;
    border: 1px solid #D8DCDF;
    color: #004276;
    display: block;
    font-weight: normal;
    opacity: 0.7;
    padding: 0.2em;
    text-align: right;
    text-decoration: none;
}
#calendar table td a:hover {
    background-color: #F6F6F6;
    border: 1px solid #CDD5DA;
    color: #111111;
}
#calendar table td.current a {
    font-weight: bold;
    opacity: 1;
}
#calendar table td.today a {
    background-color: #FBF8EE;
    border: 1px solid #FCD3A1;
    color: #444444;
    font-weight: bold;
    opacity: 1;
}

Чтобы первый день недели был не воскресенье, а понедельник, нужно найти строку:
$iFirstDayDow = (int)date('w', mktime(0, 0, 0, $iMonth, 1, $iYear));
и после неё добавить:
$iFirstDayDow = $iFirstDayDow - 1;
if($iFirstDayDow == -1) {
$iFirstDayDow = 6;
}

Скачать архив с примером

Если вам понравилась статья, вы можете отблагодарить автора любой суммой, какую сочтете для себя приемлемой:
Остались вопросы по статье? Задайте их прямо сейчас!
Похожие записи
WordPress подгрузка постов кнопкой показать еще или бесконечным скроллом

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

WordPress Ajax

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

Отправка формы без перезагрузки страницы на PHP и Ajax

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

PHP классы, объекты, методы

Абсолютно любой предмет из нашей жизни мы можем описать по его характеристикам и состоянию, а так же воздействовать на это состояние. Например, ваш автомобиль имеет определенный цвет, марку, двигатель и т.д. Кроме того он может ехать, стоять, набирать или сбавлять Читать далее

Удалить значение из массива на PHP

Удалить значение из массива по ключу на PHP довольно простая задача, но вот когда необходимо удалить элемент массива именно по значению, то тут возникают небольшие сложности. Вроде бы банальная задача, но придется воспользоваться небольшой хитростью. В этой статье рассмотрим как Читать далее

Создание чат-бота для Viber

В этой статье рассмотрим как создать простого чат-бота для Viber, который будет принимать и отправлять сообщения в чат. Шаг 1 Итак, для начала необходимо зарегистрироваться в сервисе Viber Admin Panel по этой ссылке. Шаг 2 Создаём бота. Для этого заполняем Читать далее

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

*

code