mithril.js calendar
by Cybolic
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tachyons/4.11.1/tachyons.min.css">
<script src="https://unpkg.com/mithril/mithril.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Calendar</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"
integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
</head>
<body>
<div class="container col-sm-4 col-md-7 col-lg-4 mt-5">
<div class="card">
<h3 class="card-header" id="monthAndYear"></h3>
<table class="table table-bordered table-responsive-sm" id="calendar">
<thead>
<tr>
<th>Sun</th>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
</tr>
</thead>
<tbody id="calendar-body">
</tbody>
</table>
<div class="form-inline">
<button class="btn btn-outline-primary col-sm-6" id="previous" onclick="previous()">Previous</button>
<button class="btn btn-outline-primary col-sm-6" id="next" onclick="next()">Next</button>
</div>
<br/>
<form class="form-inline">
<label class="lead mr-2 ml-2" for="month">Jump To: </label>
<select class="form-control col-sm-4" name="month" id="month" onchange="jump()">
<option value=0>Jan</option>
<option value=1>Feb</option>
<option value=2>Mar</option>
<option value=3>Apr</option>
<option value=4>May</option>
<option value=5>Jun</option>
<option value=6>Jul</option>
...
JavaScript
const locale_dow = {"en":0,"ar-dz":0,"ar-kw":0,"ar-ly":6,"ar-ma":6,"ar-sa":0,"ar":6,"bn":0,"bo":0,"dv":7,"en-ca":0,"en-il":0,"es-us":0,"fa":6,"fr-ca":0,"gu":0,"he":0,"hi":0,"ja":0,"kn":0,"ko":0,"ku":6,"lo":0,"ml":0,"mn":0,"mr":0,"ne":0,"pa-in":0,"pt-br":0,"si":0,"ta":0,"te":0,"th":0,"tzm-latn":6,"tzm":6,"zh-hk":0,"zh-tw":0};
function getLocale () {
let lang = 'en';
const known_locales = Object.keys(locale_dow);
const precise_matches = navigator.languages.filter(lang =>
known_locales.includes(lang.toLowerCase())
);
if (precise_matches.length) {
lang = precise_matches[0].toLowerCase();
} else {
const partial_matches = navigator.languages.filter(lang =
known_locales.includes(lang.split('-')[0].toLowerCase())
);
if (partial_matches.length) {
lang = partial_matches[0].split('-')[0].toLowerCase();
}
}
return lang;
}
function getLocaleFirstDayOfWeek (locale) {
locale = locale.toLowerCase();
const locale_base = locale.split('-').shift();
return locale_dow[locale] != null
? locale_dow[locale]
: locale_dow[locale_base] != null
? locale_dow[locale_base]
: 1;
}
function getMonthMatrix (locale, month, year) {
const dow = getLocaleFirstDayOfWeek(locale);
let first_day = (new Date(year, month)).getDay() - dow;
if (first_day < 0) {
first_day = first_day + 7;
}
const matrix = [];
// creating all cells
const days_in_month = daysInMonth(month, year);
let date = 1;
for (let i = 0; i < 6; i++) {
// creates a table row
let row = [];
//creating individual cells, filing them up with data.
for (let j = 0; j < 7; j++) {
if (i === 0 && j < first_day) {
row.push({ text: "" });
} else if (date > days_in_month) {
break;
} else {
const cell = {};
cell.text = date;
if (date === today.getDate() && year === today.getFullYear() && month === today.getMonth()) {
cell.today = true;
} // color today's date
...