I'm a beginner developer and I'm building a calendar for smartphones. I'm using HTML, CSS and JS. I'm not entirely done with the project yet, however, I have the feeling that I'm making a messy code. I'll be posting the link to the git + the code in here, so you can better read it/clone, and help me with design patterns, etc...
P.S.: The project was developed using the IPhoneX resolution (375 x 812). It is not responsive yet, so I would recommend running the code using the resolution above.
Git link: https://github.com/LucasBiazi/Mobile_Calendar_HTML_CSS_JS
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Calendar</title>
<script src="../script/script.js"></script>
<link rel="stylesheet" href="../css/style.css" />
</head>
<!-- As soon as the page loads, fulfills the table. -->
<body onload="load_DB(new Date().getFullYear(), new Date().getMonth())">
<div class="main">
<div class="title">
<span class="year_title" id="year_title"></span>
<span class="month_title" id="month_title"></span>
</div>
<div class="calendar">
<div id="month_days" class="month_days">
<table id="days">
<tr>
<th style="color: lightsalmon">Sun</th>
<th class="even">Mon</th>
<th>Tue</th>
<th class="even">Wed</th>
<th>Thu</th>
<th class="even">Fri</th>
<th style="color: lightsalmon">Sat</th>
</tr>
</table>
</div>
<!-- Future implementations. -->
<div class="data">
<div class="data_content">
<p style="color: black; font-size: 20px">No content.</p>
</div>
</div>
</div>
<div class="buttons">
<!-- Reteats a month. -->
<button
style="
animation: display_button_back 1s ease;
position: relative;
"
onclick="retreat_month(parseInt(document.getElementById('year_title').textContent),
identify_month(document.getElementById('month_title').textContent))"
>
<img
src="../../media/left-arrow-line-symbol.svg"
style="width: 35px; height: 35px"
alt="back"
/>
</button>
<!-- Shows current month. -->
<button
style="animation: display_opacity_zoom 1s ease-out;"
onclick="advance_month(new Date().getFullYear(), new Date().getMonth() - 1)"
>
T
</button>
<!-- Advances a month. -->
<button
style="
animation: display_button_next 1s ease;
position: relative;
"
onclick="advance_month(parseInt(document.getElementById('year_title').textContent),
identify_month(document.getElementById('month_title').textContent))"
>
<img
src="../../media/right-arrow-angle.svg"
style="width: 35px; height: 35px"
alt="next"
/>
</button>
</div>
</div>
</body>
</html>
CSS:
* {
padding: 0px;
margin: 0px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-weight: lighter;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-image: url(../../media/grass.jpg);
/* Blurring the background. Applies behind the element... */
backdrop-filter: blur(9px);
background-size: cover;
}
@keyframes display_data {
0% {
transform: scale3d(0.25, 0, 1);
}
25% {
transform: scale3d(0.5, 0, 1);
}
50% {
transform: scale3d(0.1, 0, 1);
}
75% {
transform: scale3d(0.1, 1.2, 1);
}
100% {
transform: scale3d(1, 1, 1);
}
}
@keyframes display_month_days {
from {
opacity: 0%;
}
to {
opacity: 100%;
}
}
@keyframes display_button_back {
0% {
right: 25px;
transform: scale3d(0.75, 0.75, 1);
}
100% {
right: 0px;
transform: scale3d(1, 1, 1);
}
}
@keyframes display_button_next {
0% {
left: 25px;
transform: scale3d(0.75, 0.75, 1);
}
100% {
left: 0px;
transform: scale3d(1, 1, 1);
}
}
@keyframes display_opacity_zoom {
from {
opacity: 0%;
transform: scale3d(0.5, 0.5, 1);
}
to {
opacity: 100%;
transform: scale3d(1, 1, 1);
}
}
.main {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
color: white;
background-color: rgba(0, 0, 0, 0.65);
}
.title {
margin-top: 7%;
height: 80px;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
animation: display_opacity_zoom 1s ease-out;
}
.year_title {
margin-left: 5px;
font-size: 40px;
letter-spacing: 5px;
color: lightsalmon;
text-align: center;
}
.month_title {
margin-left: 15px;
font-size: 25px;
letter-spacing: 15px;
text-align: center;
}
.calendar {
height: 75%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.month_days {
margin-top: 10px;
width: 100%;
height: 50%;
animation: display_month_days 1s ease-in-out;
}
table {
margin-top: 20px;
width: 100%;
font-size: 22px;
}
tr,
th,
td {
background-color: none;
}
th {
width: 14%;
text-align: center;
color: white;
}
td {
width: 2.38em;
height: 2.38em;
color: white;
text-align: center;
border-radius: 50%;
}
td:hover {
background-color: black;
}
.data {
display: flex;
justify-content: center;
align-items: center;
width: 95%;
height: 30%;
background-color: rgba(255, 255, 255, 0.9);
border: none;
border-radius: 5px;
animation: display_data 0.8s ease;
}
.data_content {
width: 95%;
height: 95%;
}
.other_month {
background: none;
color: rgba(175, 175, 175, 0.45);
}
.buttons {
width: 100vw;
height: 70px;
display: flex;
justify-content: space-around;
align-items: flex-start;
}
button {
width: 60px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
background: none;
border: none;
font-size: 35px;
font-weight: 400;
color: white;
}
JS:
// Returns the day of the week in which the month starts.
starting_day = (year, month) => new Date(year, month, 1).getDay();
// Returns the amount of days in a month.
total_month_days = (year, month) => new Date(year, month + 1, 0).getDate();
// Set the background color of the cell that contains today's day.
function is_today(months, cell) {
if (
new Date().getFullYear() ==
parseInt(document.getElementById("year_title").textContent) &&
months[new Date().getMonth()].month ==
document.getElementById("month_title").textContent &&
cell.textContent == new Date().getDate()
) {
cell.style.background = "rgba(255, 160, 122, 0.8)";
}
}
// Changes color if it is a weekend.
color_weekend = (let_value, cell) => {
if (let_value == 6 || let_value == 0) cell.style.color = "lightsalmon";
};
// Populates the DB.
function load_DB(year, month) {
let counter = 1;
const table = document.getElementById("days");
const date_object = new Date(year, month);
// Array containing months names, starting_day()_+ total_month_days().
const months = [
{
// Month 0
month: "January",
first_day: starting_day(date_object.getFullYear(), 0),
days: Array(total_month_days(date_object.getFullYear(), 0)),
},
{
// Month 1
month: "February",
first_day: starting_day(date_object.getFullYear(), 1),
days: Array(total_month_days(date_object.getFullYear(), 1)),
},
{
// Month 2
month: "March",
first_day: starting_day(date_object.getFullYear(), 2),
days: Array(total_month_days(date_object.getFullYear(), 2)),
},
{
// Month 3
month: "April",
first_day: starting_day(date_object.getFullYear(), 3),
days: Array(total_month_days(date_object.getFullYear(), 3)),
},
{
// Month 4
month: "May",
first_day: starting_day(date_object.getFullYear(), 4),
days: Array(total_month_days(date_object.getFullYear(), 4)),
},
{
// Month 5
month: "June",
first_day: starting_day(date_object.getFullYear(), 5),
days: Array(total_month_days(date_object.getFullYear(), 5)),
},
{
// Month 6
month: "July",
first_day: starting_day(date_object.getFullYear(), 6),
days: Array(total_month_days(date_object.getFullYear(), 6)),
},
{
// Month 7
month: "August",
first_day: starting_day(date_object.getFullYear(), 7),
days: Array(total_month_days(date_object.getFullYear(), 7)),
},
{
// Month 8
month: "September",
first_day: starting_day(date_object.getFullYear(), 8),
days: Array(total_month_days(date_object.getFullYear(), 8)),
},
{
// Month 9
month: "October",
first_day: starting_day(date_object.getFullYear(), 9),
days: Array(total_month_days(date_object.getFullYear(), 9)),
},
{
// Month 10
month: "November",
first_day: starting_day(date_object.getFullYear(), 10),
days: Array(total_month_days(date_object.getFullYear(), 10)),
},
{
// Month 11
month: "December",
first_day: starting_day(date_object.getFullYear(), 11),
days: Array(total_month_days(date_object.getFullYear(), 11)),
},
];
// Prints the name of the current month and year.
document.getElementById("year_title").textContent = date_object.getFullYear();
document.getElementById("month_title").textContent =
months[date_object.getMonth()].month;
// Month days that will appear in the first row.
const number_of_cells_in_the_first_row =
7 - months[date_object.getMonth()].first_day;
// Month days that will appear after the first row.
let normal_days = number_of_cells_in_the_first_row + 1;
// Creates + populates the 5 last rows.
for (let r = 0; r < 5; r++) {
let row = table.insertRow(r + 1);
let cell;
// Creates + populates 7 cells in each row.
for (let x = 0; x < 7; x++) {
cell = row.insertCell(x);
cell.textContent = normal_days;
is_today(months, cell);
color_weekend(x, cell);
normal_days++;
// Filling the rest of the table with the days of the next month(gray days).
if (normal_days > months[date_object.getMonth()].days.length + 1) {
// Next month days are always lowlighted.
if (x == 6 || x == 0) cell.style.color = "rgba(175, 175, 175, 0.45)";
cell.textContent = counter++;
cell.className = "other_month";
}
}
}
// Creates + populates the 1 row.
for (let i = 0; i < 1; i++) {
let row = table.insertRow(i + 1);
let cell;
let number_of_blank_cells = 7 - number_of_cells_in_the_first_row;
// Populates it.
for (let y = 0; y < number_of_cells_in_the_first_row; y++) {
cell = row.insertCell(0);
cell.textContent = number_of_cells_in_the_first_row - y;
is_today(months, cell);
color_weekend(y, cell);
}
// Filling the rest of the table (next month days).
for (let w = 0; w < number_of_blank_cells; w++) {
cell = row.insertCell(0);
if (months[date_object.getMonth() - 1]) {
cell.textContent = months[date_object.getMonth() - 1].days.length--;
cell.className = "other_month";
} else {
cell.textContent = months[date_object.getMonth() + 11].days.length--;
cell.className = "other_month";
}
}
}
}
// Converts the month name to the month number (January = 0).
function identify_month(string) {
const all_months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
let i = 0;
while (string != all_months[i]) {
i++;
}
return i;
}
// Advancecs a month.
function advance_month(year, month) {
// Cleaning table.
const table = document.getElementById("days");
for (let i = 0; i < 6; i++) {
table.deleteRow(1);
}
// Add new data.
month++;
load_DB(year, month);
}
// Retreats a month.
function retreat_month(year, month) {
// Cleaning table.
const table = document.getElementById("days");
for (let i = 0; i < 6; i++) {
table.deleteRow(1);
}
month--; // Add new data.
load_DB(year, month);
}