Skip to content

Instantly share code, notes, and snippets.

@peteeveleigh
Last active October 23, 2018 19:45
Show Gist options
  • Save peteeveleigh/0a74616b69357885e149dac5aaea358e to your computer and use it in GitHub Desktop.
Save peteeveleigh/0a74616b69357885e149dac5aaea358e to your computer and use it in GitHub Desktop.
Adapted Twig calendar from https://gist.github.com/aknosis/3932192
.calendar {
tbody td {
border: 1px solid #dedede;
}
&__day {
&--available {
}
&--booked {
background-color: #6390a3;
}
&--booked-pm {
background: linear-gradient(-45deg, #6390a3 50%, transparent 50%);
}
&--booked-am {
background: linear-gradient(-45deg, transparent 50%, #6390a3 50%);
&.calendar__day--booked-pm {
background: #6390a3;
}
}
}
}
{#
Thanks to https://gist.github.com/aknosis/3932192
time can be any string acceptable by http://www.php.net/strtotime, the
template will output that time's month.
If you don't want to pass in a date you can set time like this:
{% set time = "now"|date("U") %}
{% set time = "December 2012"|date("U") %}
How ever you want to output items onto the calendar is a different issue,
but I'd assume pushing everything into an array numerically indexed by that day:
$days = array(1=>array('Something on the first'),31=>array('Halloween'));
#}
{#
since we're loading this via ajax we want to check for some querystring params
if none are found then get the property entry a different way
#}
{% set pid = craft.request.getParam('id') ?? null %}
{% set date = craft.request.getParam('d') ?? null %}
{% if date is not null %}
{% set time = date|date("U") %}
{% else %}
{% set time = "now"|date("U") %}
{% endif %}
{% if pid %}
{% set property = craft.entries().id(pid).first() %}
{% else %}
{% set property = craft.entries().slug(craft.request.segment(2)).first() %}
{% set pid = property.id %}
{% endif %}
{# get the availability matrix - this contains dates that are booked #}
{% set availability = property.availability %}
{% set prevMonth = time|date_modify('-1 month')|date('M') %}
{% set month = time|date('M') %}
{% set nextMonth = time|date_modify('+1 month')|date('M') %}
{% set year = time|date('Y') %}
{# get an array of unavailable dates for this month #}
{% set unavailable = [] %}
{% for row in availability %}
{% if row.fromDate|date('M') == month or nextMonth == month or prevMonth == month %}
{% set unavailable = unavailable|merge([row.fromDate|date('U')]) %}
{% endif %}
{# get the number of days between the start and end dates of this booking #}
{% set difference = row.toDate|date('U') - row.fromDate|date('U') %}
{% set bookedDays = difference / 86400 %}
{# add the bookedDays to the unavailable dates #}
{% for bookedDay in range(1, bookedDays) %}
{% set unavailable = unavailable|merge([row.fromDate|date_modify('+' ~ bookedDay ~ ' days')|date('U')]) %}
{% endfor %}
{% endfor %}
<div class="js-calendar">
<table class="calendar">
<thead>
<tr>
<th colspan="7" class="center">
{{ time|date('F Y') }}
</th>
</tr>
<tr>
<th width="14.28%">Sun</th>
<th width="14.28%">Mon</th>
<th width="14.28%">Tue</th>
<th width="14.28%">Wed</th>
<th width="14.28%">Thu</th>
<th width="14.28%">Fri</th>
<th width="14.28%">Sat</th>
</tr>
</thead>
<tbody>
<tr>
{% set daysInMonth = time|date('t') %}
{% set startDow = time|date('F 1\\s\\t Y')|date('w') %}
{% set dow = startDow %}
{% for day in range(1,daysInMonth) %}
{% if loop.first and startDow != 0 %}
<td colspan="{{ startDow }}"></td>
{% endif %}
{% set booked = false %}
{% set previousDayBooked = false %}
{% set nextDayBooked = false %}
{% set thisDay = day ~ ' ' ~ month ~ ' ' ~ year %}
{% set previousDay = thisDay|date_modify('-1 day')|date('U') %}
{% set nextDay = thisDay|date_modify('+1 day')|date('U') %}
{% if thisDay|date('U') in unavailable %}
{% set booked = true %}
{% endif %}
{% if previousDay in unavailable %}
{% set previousDayBooked = true %}
{% endif %}
{% if nextDay in unavailable %}
{% set nextDayBooked = true %}
{% endif %}
{% set class = '' %}
{# apply css classes based on the booked status of this day, the previous day and the following day #}
{% if booked %}
{% if previousDayBooked %}
{% set class = 'calendar__day--booked-am' %}
{% endif %}
{% if nextDayBooked %}
{% set class = 'calendar__day--booked-pm' %}
{% endif %}
{% if previousDayBooked and nextDayBooked %}
{% set class = 'calendar__day--booked' %}
{% endif %}
{% endif %}
<td class="{{ class }}" >
<div title="{{thisDay|date('U') in unavailable ? 'Booked' : 'Available'}}">
<div>{{ day }}</div>
<div>
{# day content here #}
</div>
</div>
</td>
{% if loop.last and dow != 6 %}
<td colspan="{{ 6 - dow }}">&nbsp;</td>
{% endif %}
{% if dow == 6 %}
{% set dow = 0 %}
</tr>
<tr>
{% else %}
{% set dow = dow + 1 %}
{% endif %}
{% endfor %}
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">
{% if date >= now|date('U') %}
<a href="/properties/calendar?id={{pid}}&amp;d={{time|date_modify('-1 month')|date('U')}}" class="js-calendarUpdate" data-id="{{pid}}"><i class="fas fa-angle-double-left"></i> {{ time|date_modify("-1 month")|date('M Y') }}</a>
{% endif %}
</td>
<td></td>
<td colspan="3" style="text-align: right"><a class="js-calendarUpdate" href="/properties/calendar?id={{pid}}&amp;d={{time|date_modify('+1 month')|date('U')}}">{{ time|date_modify("+1 month")|date('M Y') }} <i class="fas fa-angle-double-right"></a></td>
</tr>
</tfoot>
</table>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment