Skip to content

*Final Solution Antonio Rufino Casasus #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 5 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
`#html` `#css` `#js` `#dom` `#localstorage` `#JSON` `#master-in-software-engineering`

# CALENDAR JS

## Introduction

<p>
Expand All @@ -10,29 +12,16 @@ In this project you will have to create a calendar using the main web fundamenta

The calendar must be interactive for the users allowing them to create events without refreshing the whole page.

## What are the main goals in this project?

- Improve your knowledge of JavaScript
- Learn to work with the HTML DOM
- Learn to work with localStorage
- Learn and improve your knowledge in logic processes
- Learn to validate forms using Javascript
- Learn to work with JSON format

## Requirements

- You must develop this project using a single HTML page
- You cannot use third-party libraries
- You must use localStorage to store all the events, this way, if you reload the page, the events will remain stored in the browser
- You must use semantic HTML5 elements for all the contents of the application

## Repository
## Project

Check with your tech lead the project requirements for this pill.
Project developed:

## Resources
![image](https://github.com/devs-toni/appcaljs/assets/103459716/1a136890-3d9f-476e-bbea-199716c19e02)

- [JavaScript HTML DOM](https://www.w3schools.com/js/js_htmldom.asp)
- [JavaScript Dates](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Date)
- [LocalStorage](https://developer.mozilla.org/es/docs/Web/API/Window/localStorage)
- [JavaScript Timeout](https://www.w3schools.com/jsref/met_win_settimeout.asp)
191 changes: 191 additions & 0 deletions events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
let reminders = [];
let allEvents = [];

function loadEvents() {
allEvents = getStorage("events") ? getStorage("events") : [];
allEvents.forEach((event) => {
event.remind ? reminders.push({
id: event.id,
title: event.title,
initDate: event.initDate,
endDate: event.endDate,
time: event.time,
description: event.description,
type: event.type,
remind: event.remind,
finished: event.finished,
}) : null;
chooseDateEventAndPaint(event);
});
}

const addEvent = (e) => {
e.preventDefault();
const monthEvent = new Date(initDate.value).getMonth();
if (monthEvent === navigator) {
const startDate = setDateFormValues(initDate.value, extractTime(initTime.value));
const finalDate = setDateFormValues(endDate.value, extractTime(endTime.value));
if (finalDate.getMonth() - startDate.getMonth() <= 1) {
if (startDate < finalDate) {
if (startDate.getTime() + 600000 > new Date().getTime()) {
const event = createEvent(startDate, finalDate);
time.value && reloadReminderEvents(event);
reloadEvents(event);
saveStorage("events", allEvents);
chooseDateEventAndPaint(event);
initModalEvent();
form.reset();
document.querySelector("#addModal.is-visible").classList.remove(isVisible);
document.body.style.overflow = "auto";
} else openError(1);
} else openError(2);
} else openError(3);
} else openError(4);
}

function createEvent(startDate, finalDate) {
const event = {
id: `id_${Date.now()}`,
title: title.value,
initDate: toIsoString(startDate),
endDate: toIsoString(finalDate),
time: time.value ? time.value : "",
description: description.value ? description.value : "",
type: type.value ? type.value : "",
remind: time.value ? true : undefined,
finished: false
}
return event;
}

function chooseDateEventAndPaint(event) {
const month = new Date(event.initDate).getMonth();
const monthEnd = new Date(event.endDate).getMonth();
const { totalDays, daysInMonth1 } = getDaysOfEvent(event.initDate, event.endDate);
totalDays.forEach((day, i) => {
let daySquare;
if (monthEnd - month > 0) {
if (i <= daysInMonth1) {
daySquare = document.querySelector(`div[data-day="${day}"][data-month="${month}"]`);
} else {
daySquare = document.querySelector(`div[data-day="${day}"][data-month="${monthEnd}"]`);
}
} else {
daySquare = document.querySelector(`div[data-day="${day}"][data-month="${month}"]`);
}
if (totalDays.length === 1) paintEvent(event, daySquare, true, true);
else {
if (i === 0) paintEvent(event, daySquare, true, false);
else if (i === totalDays.length - 1) paintEvent(event, daySquare, false, true);
else paintEvent(event, daySquare);
}
});
}

function paintEvent(event, daySquare, paintInit, paintEnd) {
const newDomEvent = document.createElement("div");
const strTimeInit = getFullTimeFromString(event.initDate);
const strTimeEnd = getFullTimeFromString(event.endDate);
newDomEvent.innerHTML = `<p event-id=${event.id}>${event.title}<p/>`;
newDomEvent.innerHTML += `<p event-id=${event.id}>${paintInit ? strTimeInit : ''}${paintInit && paintEnd ? ' - ' : ''}${paintEnd ? strTimeEnd : ''}</p>`;
newDomEvent.innerHTML += `<p event-id=${event.id}>${paintInit || paintEnd ? event.type : ''}</p>`;
newDomEvent.innerHTML += `<p event-id=${event.id}>${paintInit ? event.description : ''}</p>`;
newDomEvent.classList.add("day-event");
newDomEvent.setAttribute('event-id', event.id);
newDomEvent.addEventListener("click", (e) => openEvent(e));
newDomEvent.setAttribute('data-open', 'eventModal');

if (event.remind === false) newDomEvent.style.backgroundColor = 'orange';
if (event.finished) newDomEvent.style.backgroundColor = 'rgb(203 55 55)';

daySquare.append(newDomEvent);
}

const removeEvent = (e) => {
e.preventDefault();
allEvents = arrayRemove(allEvents, idEvent.value);
removeStorage("events");
saveStorage("events", allEvents);

const month = new Date(initEventDate.value).getMonth();
const monthEnd = new Date(endEventDate.value).getMonth();
const { totalDays, daysInMonth1 } = getDaysOfEvent(initEventDate.value, endEventDate.value);

totalDays.forEach((day, i) => {
let daySquare;
if (monthEnd - month > 0) {
if (i <= daysInMonth1) {
daySquare = document.querySelector(`div[data-day="${day}"][data-month="${month}"]`);
} else {
daySquare = document.querySelector(`div[data-day="${day}"][data-month="${monthEnd}"]`);
}
} else {
daySquare = document.querySelector(`div[data-day="${day}"][data-month="${month}"]`);
}
Array.from(daySquare.children).forEach(el => {
if (idEvent.value === el.getAttribute("event-id")) el.remove();
});
});
document.querySelector("#eventModal.is-visible").classList.remove(isVisible);
document.body.style.overflow = 'auto';
}

function getDaysOfEvent(initDate, endDate) {
const dateStart = new Date(initDate);
const dateFinal = new Date(endDate);;
const year = dateStart.getFullYear();
const dayInit = dateStart.getDate();
const dayFinal = dateFinal.getDate();
const monthInit = dateStart.getMonth();
const monthEnd = dateFinal.getMonth();
let totalDays = [];

if (monthEnd - monthInit > 0) {
const daysInMonth = new Date(year, monthInit, 0).getDate();
const daysInMonth1 = (daysInMonth - dayInit);
const daysInMonth2 = dayFinal;
const numberDays = daysInMonth1 + daysInMonth2;
for (let i = 0; i <= numberDays; i++) {
if (i <= daysInMonth1) totalDays.push(i + dayInit);
}
for (let x = 1; x <= (numberDays - daysInMonth1); x++) {
totalDays.push(x);
}
const objectToReturn = {
totalDays: totalDays,
daysInMonth1: daysInMonth1,
}
return objectToReturn;

} else {
const numberDays = dayFinal - dayInit;
for (let i = 0; i <= numberDays; i++) {
totalDays.push(i + dayInit);
}
return { totalDays: totalDays };
}
}

function disableEvent(task) {
openAlert(task, "end");
removeStorage("events");
allEvents.find(event => event.id === task.id).finished = true;
saveStorage("events", allEvents);
setTimeout(() => {
if (document.querySelector("#endAlert.is-visible")) {
document.querySelector("#endAlert.is-visible").classList.remove(isVisible);
}
}, 5000);
}

function remindEvent(task) {
openAlert(task, "remind");
removeStorage("events");
allEvents.find(event => event.id === task.id).remind = false;
saveStorage("events", allEvents);
setTimeout(() => {
if (document.querySelector("#remindAlert.is-visible")) {
document.querySelector("#remindAlert.is-visible").classList.remove(isVisible);
}
}, 5000);
}
84 changes: 84 additions & 0 deletions forms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const checkboxEndDate = document.querySelector("#existEndDate");
const checkboxExpiration = document.querySelector("#expiration");
const containerPreviousTime = document.querySelector("#previousTime");
const containerEndDate = document.querySelector("#showEndDate");
const initDate = document.querySelector("#initDate");
const initTime = document.querySelector("#initTime");
const title = document.querySelector("#title");
const description = document.querySelector("#description");
const type = document.querySelector("#type");
const endDate = document.querySelector("#endDate");
const endTime = document.querySelector("#endTime");
const time = document.querySelector("#time");
const containerExpiration = document.querySelector("#showExpiration");

function initForm() {
checkboxEndDate.addEventListener("change", showEndDate);
checkboxExpiration.addEventListener("change", showPreviousTime);
form.addEventListener("submit", addEvent);
formEvent.addEventListener("submit", removeEvent);
}

const showEndDate = () => {
if (checkboxEndDate.checked) {
containerEndDate.classList.add(isVisible);
containerExpiration.classList.add(isVisible);
checkboxExpiration.checked = true;
containerPreviousTime.classList.add(isVisible);
endDate.required = true;
endTime.required = true;
time.required = true;

} else {
containerEndDate.classList.remove(isVisible);
containerExpiration.classList.remove(isVisible);
endDate.required = false;
endTime.required = false;
time.required = false;
}
};

function hideEndDateAndRemind() {
containerEndDate.classList.remove(isVisible);
containerExpiration.classList.remove(isVisible);
checkboxEndDate.checked = false;
checkboxExpiration.checked = false;
endDate.required = false;
endTime.required = false;
time.required = false;
}

function setDatesInForm(date, timeInit, timeEnd) {
initDate.value = date;
initTime.value = timeInit;
endDate.value = date;
endTime.value = timeEnd;
title.value = '';
description.value = '';
type.value = '';
}

function setEventData(event) {
document.querySelector("#titleEvent").textContent = event.title;
document.querySelector("#startDate").textContent = getStrDisplayDateTime(new Date(event.initDate), userLang);
document.querySelector("#finalDate").textContent = getStrDisplayDateTime(new Date(event.endDate), userLang);
document.querySelector("#descriptionEvent").textContent = event.description ? event.description : "Not Selected";
document.querySelector("#timeEvent").textContent = event.time ? event.time + " minutes" : "Not Selected";
document.querySelector("#typeEvent").textContent = event.type ? event.type : "Not Selected";
document.querySelector("#typeEvent").style.textTransform = "capitalize";
document.querySelector("#initEventDate").value = toIsoString(new Date(event.initDate));
document.querySelector("#endEventDate").value = toIsoString(new Date(event.endDate));
document.querySelector("#idEvent").value = event.id;
}

const showPreviousTime = () => {
if (checkboxExpiration.checked) {
containerPreviousTime.classList.add(isVisible);
time.required = true;

} else {
containerPreviousTime.classList.remove(isVisible);
time.required = false;
time.value = '';
}
};
Loading