In this article, we’ll explore how to create a dynamic calendar application using SpreadsheetWeb. This guide will walk you through two different implementations: one where users can interactively add and remove events, and another where events are populated from an Excel table. We will also discuss how to style and embed in the user interface. Let’s dive into the details!
Setting Up the Environment
Before we begin with the code, it's essential to understand the components and environment setup:
- SpreadsheetWeb Platform: This is where our application lives, providing us with the necessary tools like Script and Style features.
- External Calendar Library: We’ll be using FullCalendar, a popular JavaScript library that offers a full-featured interface.
Implementation 1: Interactive Calendar
This version allows users to interact directly with the calendar by adding, editing, and deleting events. Below is the JavaScript code that powers this functionality:
// Include FullCalendar CSS
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.css';
document.getElementsByTagName('head')[0].appendChild(link);
// Include FullCalendar JS
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.js", function() {
$(document).ready(function() {
// Initialize the calendar
$('.my-calendar').fullCalendar({
header: {
left: 'prev,next today', // Navigation buttons
center: 'title', // Calendar title
right: 'month,agendaWeek,agendaDay' // View options
},
defaultDate: '2018-07-12', // Starting date
editable: true, // Allows editing of events
selectable: true, // Allows date selection
selectHelper: true, // Display a placeholder while selecting
eventLimit: true, // Limits the number of events per day
// Predefined events
events: [
{
title: 'All Day Event',
start: '2018-07-01'
},
{
title: 'Long Event',
start: '2018-07-07',
end: '2018-07-10'
}
// ...additional events
],
// Event creation on day click
dayClick: function(date, jsEvent, view) {
var eventTitle = prompt('Event Title:');
if (eventTitle) {
var eventData = {
title: eventTitle,
start: date
};
$('.my-calendar').fullCalendar('renderEvent', eventData, true); // Render new event
}
},
// Event creation on date range select
select: function(start, end) {
var eventTitle = prompt('Event Title:');
if (eventTitle) {
var eventData = {
title: eventTitle,
start: start,
end: end
};
$('.my-calendar').fullCalendar('renderEvent', eventData, true); // Render new event
}
$('.my-calendar').fullCalendar('unselect');
},
// Event deletion on click
eventClick: function(event, jsEvent, view) {
var deleteEvent = confirm('Do you really want to delete this event?');
if (deleteEvent) {
$('.my-calendar').fullCalendar('removeEvents', event._id); // Remove event
}
}
});
// Date jump functionality
var dateJumpHtml = '<div id="date-jump" style="text-align:center; margin-top: 20px;">' +
'Year: <input type="number" id="jump-year" value="2018" min="1900" max="2100"> ' +
'Month: <input type="number" id="jump-month" value="7" min="1" max="12"> ' +
'Day: <input type="number" id="jump-day" value="12" min="1" max="31"> ' +
'<button id="jump-date-button">Go</button>' +
'</div>';
$('.my-calendar').after(dateJumpHtml);
// Jump to a specific date
$('#jump-date-button').on('click', function() {
var year = $('#jump-year').val();
var month = $('#jump-month').val();
var day = $('#jump-day').val();
var newDate = moment(year + '-' + month + '-' + day);
$('.my-calendar').fullCalendar('gotoDate', newDate);
});
});
});
Explanation:
- CSS and JS Loading: We dynamically load the FullCalendar CSS and JS files into the document.
- Calendar Initialization: The calendar is initialized with navigation controls and default events.
- Event Management: Users can click on a date to create an event, select a date range to create multi-day events, and click on an existing event to delete it.
- Date Jump Feature: Users can input a specific date to jump directly to it.
You can access the first implementation from this link
Implementation 2: Calendar with Excel Data Integration
In this implementation, events are read from an Excel table, making it more structured and suitable for scenarios where events are predefined.
// Include FullCalendar CSS
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.css';
document.getElementsByTagName('head')[0].appendChild(link);
// Include FullCalendar JS
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.js", function() {
$(document).ready(function() {
// Initialize the calendar
$('.my-calendar').fullCalendar({
header: {
left: 'prev,next today', // Navigation buttons
center: 'title', // Calendar title
right: 'month,agendaWeek,agendaDay' // View options
},
defaultDate: moment().format('YYYY-MM-DD'), // Current date
editable: false, // Disables editing of events
eventLimit: true, // Limits the number of events per day
events: [] // Events will be loaded from the Excel grid
});
// Function to update calendar from Excel grid
function updateCalendarFromGrid() {
try {
var inputGrid1 = pagosApp.inputGrids.byNameRange("Grid"); // Get the grid data
var gridData = inputGrid1.value();
if (typeof gridData === 'string') {
gridData = JSON.parse(gridData); // Parse if the grid data is in JSON string format
}
$('.my-calendar').fullCalendar('removeEvents'); // Clear existing events
gridData.forEach(function(row) {
var startDate = moment(row[0], "MM/DD/YYYY").format("YYYY-MM-DD");
var endDate = row[1] ? moment(row[1], "MM/DD/YYYY").format("YYYY-MM-DD") : startDate;
var time = row[2] ? moment(row[2], ["h:mm A"]).format("HH:mm") : "00:00";
var eventData = {
title: row[3],
start: startDate + "T" + time,
end: endDate + "T" + time,
color: row[4] === "High" ? "red" : row[4] === "Medium" ? "yellow" : "green" // Priority-based coloring
};
$('.my-calendar').fullCalendar('renderEvent', eventData, true); // Render the event
});
} catch (e) {
console.error("Error processing grid data: ", e);
}
}
updateCalendarFromGrid(); // Initial load
var inputGrid1 = pagosApp.inputGrids.byNameRange("Grid");
if (typeof inputGrid1 !== 'undefined' && inputGrid1.on) {
inputGrid1.on("change", updateCalendarFromGrid); // Update on grid change
} else {
console.error("inputGrid1 is undefined.");
}
// Date jump functionality
var dateJumpHtml = '<div id="date-jump" style="text-align:center; margin-top: 20px;">' +
'Year: <input type="number" id="jump-year" value="' + moment().format('YYYY') + '" min="1900" max="2100"> ' +
'Month: <input type="number" id="jump-month" value="' + moment().format('MM') + '" min="1" max="12"> ' +
'Day: <input type="number" id="jump-day" value="' + moment().format('DD') + '" min="1" max="31"> ' +
'<button id="jump-date-button">Go</button>' +
'</div>';
$('.my-calendar').after(dateJumpHtml);
// Jump to a specific date
$('#jump-date-button').on('click', function() {
var year = $('#jump-year').val();
var month = $('#jump-month').val();
var day = $('#jump-day').val();
var newDate = moment(year + '-' + month + '-' + day);
$('.my-calendar').fullCalendar('gotoDate', newDate);
});
});
});
Explanation:
- Excel Grid Integration: The code reads event data from an Excel grid, converting it into events on the calendar. This allows users to manage their events in a structured Excel format.
- Priority-Based Coloring: Events are color-coded based on their priority (High, Medium, Low), making it easier to distinguish between different types of events.
- Automatic Updates: The calendar automatically updates when changes are made to the Excel grid.
You can access the second implementation from this link
Styling the Calendar
To ensure the calendar fits into the UI, we can apply some custom CSS. Here’s the CSS code used:
.my-calendar {
width: 100%;
max-width: 900px;
margin: 0 auto; /* Center the calendar */
}
#date-jump {
text-align: center;
margin-bottom: 20px;
}
#date-jump input {
width: 60px;
margin: 0 5px;
}
This CSS centers the calendar within its container and styles the date jump inputs for a cleaner look.
Embedding the Calendar in the UI
Finally, to display the calendar in your application’s user interface, you’ll need to add an HTML element to the content label in SpreadsheetWeb’s UI editor. Here’s the HTML snippet:
<div class="my-calendar"></div>
This div acts as the placeholder where the FullCalendar will be rendered.
Conclusion
By following the steps outlined in this article, you can create a fully functional and dynamic calendar application within SpreadsheetWeb. Whether you want users to interactively manage events or display events from an Excel grid, these implementations provide a robust solution. The use of custom styling and UI integration ensures that the calendar not only works well but also looks great within your application.
This guide should provide you with the foundation to build and expand upon these concepts in your own SpreadsheetWeb projects.