Multilanguage calendar
by Qwerty_Wasd
HTML
<div class="control">
<input type="number" id="month" min="1" max="12" placeholder="Месяц" value="6">
<input type="number" id="year" min="1970" placeholder="Год" value="2018">
<button>ru</button>
<button>en</button>
<button>uk</button>
<button>fr</button>
<button>de</button>
<button>pl</button>
<button>ar</button>
</div>
<output></output>
CSS
.calendar {
display: grid;
grid-template-columns: 3.125rem 3.125rem 3.125rem 3.125rem 3.125rem 3.125rem 3.125rem;
grid-template-rows: 3.125rem 3.125rem 3.125rem 3.125rem 3.125rem 3.125rem 3.125rem 3.125rem;
grid-gap: 0.0625rem;
}
.calendar div {
text-align: center;
border: 0.0625rem solid #999;
}
.calendar div.blur {
color: #ccc;
}
.calendar div:nth-child(1),
.calendar div.day_name {
background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
font-weight: bold;
text-shadow: 0.0625rem 0.0625rem 0.0625rem #ffffff;
}
.calendar div:nth-child(1) {
grid-column: 1/8;
padding-right: 1rem;
font-weight: bold;
text-align: right;
font-size: 1.2rem;
}
.calendar div:nth-child(7),
.calendar div:nth-child(8) {
color: #f00;
}
.calendar div::before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.calendar div:nth-child(2) div {
font-weight: bold;
}
.control {
margin-bottom: 0.625rem;
}
output {
display: inline-block;
}
button {
text-transform: uppercase;
}
JavaScript
[...document.querySelectorAll('button')].forEach(btn => {
btn.addEventListener('click', e => {
let cl = new Calendar(+month.value, +year.value);
cl.setLocale(e.target.textContent);
cl.render('output');
});
});
class Calendar {
constructor(m = 1, y = 2018) {
this.m = m;
this.y = y;
this.prevMonth = this.startFrom();
let lsatDate = this.mDate(this.y, this.m, 0);
this.currMonth = this.fillRange(1, lsatDate.getDate());
this.nextMonth = this.fillRange(1, 7 - lsatDate.getDay());
this.locale = 'ru';
}
setLocale(lc = '') {
this.locale = lc;
}
startFrom() {
let dn = this.mDate(this.y, this.m - 1, 1).getDay() || 7,
ld = this.mDate(this.y, this.m - 1, 0).getDate();
console.log(dn, ld);
return dn !== 0 ? this.fillRange(ld - dn + 2, ld) : [];
}
mDate(y, m, d) {
return new Date(y, m, d);
}
fillRange(start, end) {
return Array(end - start + 1).fill().map((item, index) => start + index);
}
nonMonthDays(a) {
return a.map(n => `<div class="blur">${n}</div>`);
}
daysName() {
let str = '';
let d = new Date();
d.setDate(1);
while (d.getDay() !== 1) {
d.setDate(d.getDate() + 1);
}
for (var i = 0; i < 7; i++) {
str += `<div class="day_name">${d.toLocaleString(this.locale, {
weekday: 'short'
})}</div>`;
d.setDate(d.getDate() + 1)
}
return str;
}
firstLines() {
return `<div>
${this.mDate(this.y, this.m-1, 1).toLocaleString(this.locale, {
month: 'long',
year: 'numeric'
})}
</div>`;
}
render(target = 'body') {
const days = this.nonMonthDays(this.prevMonth)
.concat(this.currMonth.map(n => `<div>${n}</div>`))
.concat(this.nonMonthDays(this.nextMonth));
...