- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-16-2023 09:07 AM
I have been given a requirement to duplicate Atlassian Confluence calendar functionality in ServiceNow. I have managed to create a UI page using the Fullcalendar library that displays records from my custom table using a date field named u_start.
This is what it looks like so far:
If you click on a blue even there, it opens up the record for editing or reference. That is perfect. If you click on the white space of a date, it opens up a modal window to create a new record. That is also perfect.
What is not perfect, is that the u_start field is not populated with the date that you clicked on. Here is what the modal looks like:
What I want is for the date that was clicked on to be filled in that start field. I know I am getting the date because I have an alert setup in the code that tells me what date I clicked on. I just don't know how to get over that last hump to put it in that field.
The other thing that does not work is the date picker on each of those start and end fields. You can manually type in a date and click submit and it does create a new record correctly. But click on that little calendar icon and nothing happens.
Now, I will share my UI page code... full disclosure, I got this far by using ChatGPT - It helps me be far more productive. But, it doesn't know even close to everything and it is often wrong. I've hit a wall with it and this.
Here is the HTML section (I'm not even sure I need all this because clearly the modal is bringing up the new record form from the table... but I did what ChatGPT told me to do.)
<div id="calendar"></div>
<div id="myModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h2>Create New Record</h2>
<form id="recordForm">
<label for="startDate">Start Date:</label>
<input type="text" id="startDate" name="startDate" readonly="readonly"></input>
<label for="description">Description:</label>
<input type="text" id="description" name="description"></input>
<label for="notes">Notes:</label>
<textarea id="notes" name="notes"></textarea>
<label for="driver">Driver:</label>
<input type="text" id="driver" name="driver"></input>
<button type="submit">Save</button>
</form>
</div>
</div>
<!-- Include the FullCalendar library -->
<script src="sys_attachment.do?sys_id=ae516fef1b536550cc11fee58d4bcb1c"></script>
And here is the client script portion:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
initialView: 'dayGridMonth',
events: function(info, successCallback, failureCallback) {
// Fetch events from the 'u_logistics_shipping' table
var gr = new GlideRecord('u_logistics_shipping');
gr.query(function(response) {
var events = [];
while (gr.next()) {
var event = {
title: gr.getValue('u_description'),
start: gr.getValue('u_start'),
end: gr.getValue('u_end'),
recordSysId: gr.getValue('sys_id') // Store the record's sys_id as a custom property
};
events.push(event);
}
successCallback(events);
});
},
eventClick: function(info) {
// Get the record sys_id from the clicked event's custom property
var recordSysId = info.event.extendedProps.recordSysId;
// Open the record in a new window or navigate to it
var url = '/u_logistics_shipping.do?sys_id=' + recordSysId;
window.open(url, '_blank'); // Open in a new window/tab
// window.location.href = url; // Navigate to the record in the same window/tab
},
select: function(info) {
// Create a new record with the selected start and end dates
var gr = new GlideRecord('u_logistics_shipping');
gr.initialize();
gr.setValue('u_start', info.startStr);
gr.setValue('u_end', info.endStr);
// Set other properties of the record as needed
// Insert the new record
var sysId = gr.insert(function(response) {
if (response && response.sys_id) {
// Refresh the calendar to display the newly created event
calendar.refetchEvents();
}
});
},
dateClick: function(info) {
var clickedDate = info.dateStr;
openModal(clickedDate);
gr.setValue('u_start', clickedDate);
}
});
function openModal(clickedDate) {
var modal = new GlideModal('myModal'); // Replace 'myModal' with the ID of your modal element
modal.setTitle('New Shipment');
modal.setPreference('clickedDate', clickedDate);
modal.setPreference('table', 'u_logistics_shipping');
modal.setPreference('func', 'createNewRecord');
modal.render();
// Set the start date field value
var startDateField = document.getElementById('startDate');
startDateField.value = clickedDate;
// modal_form.setValue('u_start', startDateField.value);
alert(startDateField.value);
info.u_start = startDateField.value;
// Initialize the date picker
// $j(startDateField).datepicker();
}
calendar.render();
});
So, I would like your help solving the two problems:
1. Auto fill the u_start field. (number 1 priority)
2. Fix the date picker (if that's even possible).
Thank you!
Daniel
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-16-2023 01:49 PM
Solved it. I went with GlideModalForm instead and that worked...much better. Here is the client script.
// Add event listener to wait for the content to be loaded
document.addEventListener('DOMContentLoaded', function() {
// Get the calendar element
var calendarEl = document.getElementById('calendar');
// Initialize the FullCalendar
var calendar = new FullCalendar.Calendar(calendarEl, {
// Configure header toolbar
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
// Set the initial view
initialView: 'dayGridMonth',
// Fetch events from the 'u_logistics_shipping' table
events: function(info, successCallback, failureCallback) {
var gr = new GlideRecord('u_logistics_shipping');
gr.query(function(response) {
var events = [];
while (gr.next()) {
var event = {
title: gr.getValue('u_description'),
start: gr.getValue('u_start'),
end: gr.getValue('u_end'),
recordSysId: gr.getValue('sys_id')
};
events.push(event);
}
// Pass events to the calendar
successCallback(events);
});
},
// Event handler for clicking on an event
eventClick: function(info) {
// Get the sys_id of the record from the clicked event
var recordSysId = info.event.extendedProps.recordSysId;
// Construct the URL and open it in a new window/tab
var url = '/u_logistics_shipping.do?sys_id=' + recordSysId;
window.open(url, '_blank');
},
// Event handler for selecting a date range
select: function(info) {
// Initialize a new record
var gr = new GlideRecord('u_logistics_shipping');
gr.initialize();
gr.setValue('u_start', info.startStr);
gr.setValue('u_end', info.endStr);
// Insert the new record
gr.insert(function(response) {
if (response && response.sys_id) {
// Refresh the calendar to display the new event
calendar.refetchEvents();
}
});
},
// Event handler for clicking on a date
dateClick: function(info) {
// Open the modal with the clicked date
openModal(info.dateStr);
}
});
// Function to open the modal form
function openModal(clickedDate) {
// Create and configure the GlideModalForm
var modalform = new GlideModalForm('Logistics Shipping', 'u_logistics_shipping');
modalform.setPreference('sysparm_query', 'u_start=' + clickedDate);
modalform.render();
}
// Render the calendar
calendar.render();
});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-16-2023 01:49 PM
Solved it. I went with GlideModalForm instead and that worked...much better. Here is the client script.
// Add event listener to wait for the content to be loaded
document.addEventListener('DOMContentLoaded', function() {
// Get the calendar element
var calendarEl = document.getElementById('calendar');
// Initialize the FullCalendar
var calendar = new FullCalendar.Calendar(calendarEl, {
// Configure header toolbar
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
// Set the initial view
initialView: 'dayGridMonth',
// Fetch events from the 'u_logistics_shipping' table
events: function(info, successCallback, failureCallback) {
var gr = new GlideRecord('u_logistics_shipping');
gr.query(function(response) {
var events = [];
while (gr.next()) {
var event = {
title: gr.getValue('u_description'),
start: gr.getValue('u_start'),
end: gr.getValue('u_end'),
recordSysId: gr.getValue('sys_id')
};
events.push(event);
}
// Pass events to the calendar
successCallback(events);
});
},
// Event handler for clicking on an event
eventClick: function(info) {
// Get the sys_id of the record from the clicked event
var recordSysId = info.event.extendedProps.recordSysId;
// Construct the URL and open it in a new window/tab
var url = '/u_logistics_shipping.do?sys_id=' + recordSysId;
window.open(url, '_blank');
},
// Event handler for selecting a date range
select: function(info) {
// Initialize a new record
var gr = new GlideRecord('u_logistics_shipping');
gr.initialize();
gr.setValue('u_start', info.startStr);
gr.setValue('u_end', info.endStr);
// Insert the new record
gr.insert(function(response) {
if (response && response.sys_id) {
// Refresh the calendar to display the new event
calendar.refetchEvents();
}
});
},
// Event handler for clicking on a date
dateClick: function(info) {
// Open the modal with the clicked date
openModal(info.dateStr);
}
});
// Function to open the modal form
function openModal(clickedDate) {
// Create and configure the GlideModalForm
var modalform = new GlideModalForm('Logistics Shipping', 'u_logistics_shipping');
modalform.setPreference('sysparm_query', 'u_start=' + clickedDate);
modalform.render();
}
// Render the calendar
calendar.render();
});

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-19-2023 01:29 AM
Hello Daniel,
Thank you for sharing your insights.
I recently joined a project that utilizes fullCalendar version 4 in a custom widget. However, after upgrading the instance to Utah, we encountered some issues where certain functionality, buttons, and styles were missing. Since I'm not familiar with fullCalendar, I believe upgrading it to the latest version, preferably 6.8.1 or a newer release, would be a beneficial solution.
I was wondering if you could provide some details regarding the version of fullCalendar you utilized and the specific SN instance you have. Additionally, it would be helpful if you could explain how you integrated that particular version.
Thank you in advance for your assistance.
Regards: Afshin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-30-2023 07:19 AM
Sorry it's taken me so long to answer you. I've been out on vacation and work has piled up.
I used ChatGPT to figure it out mostly. I went to the website and downloaded the most recent library:
https://fullcalendar.io/docs/getting-started
Which is 6.1.8, I believe.
I attached the library file (index.global.min.js) to a script include.
The UI page HTML calls the script include from the HTML code with this line of code:
<!-- Include the FullCalendar library --> <script src="sys_attachment.do?sys_id=ae516fef1b536550cc11fee58d4bcb1c"></script>
Here is our servicenow version:
Build name: Tokyo
Build date: 05-15-2023_1941