Salesforce Integration in TypeScript Scheduler
This topic provides a detailed, step-by-step guide on how to seamlessly integrate the JavaScript Scheduler control into Salesforce. By integrating it into Salesforce, you can enhance productivity and streamline scheduling processes.
Prerequisites
Before getting started, ensure the following prerequisite is installed:
Configuring Salesforce
To begin the integration process, configure Salesforce by following these steps:
Sign up for a Salesforce developer account if you do not already have one. This gives you access to the necessary tools and resources for integration.
Log in with your Salesforce account.
After logging in, search for Dev Hub in the quick find search box and select Dev Hub. In the Dev Hub setup tab, ensure that the Enable Dev Hub option is enabled.

Creating a Salesforce project
Now that Salesforce is configured, let’s create a Salesforce project for the integration.
In your preferred location, create a base directory for your Salesforce project. For example, you can create a directory named salesforceApp using the following command:
mkdir salesforceAppNavigate to the base directory you created in the previous step and generate a Salesforce DX project using the following CLI command.
sf project:generate -n scheduler-salesforce-app
Authorizing the Salesforce project
Before proceeding further, you need to authorize your Salesforce project by following these steps
Run the following command to authorize your Salesforce project with your Salesforce account in the browser.
sf org:login:web -d
Open the sfdx-project.json file located in salesforceApp/scheduler-salesforce-app and update the sfdcLoginUrl with the domain URL of your Salesforce account as shown in image (fig 2). You can obtain the domain URL from the My Domain setup tab in Salesforce as shown in image (fig 1).
fig 1

fig 2

Create scratch organization
To facilitate development and testing, the creation of a scratch organization will be done using the following steps.
Run the following command to create a new scratch organization, which will provide a fresh Salesforce environment for development and testing with organization id and username as link below image.
sf org:create:scratch -f config/project-scratch-def.json
Adding static resources
To integrate the Syncfusion® scripts and styles as static resource files within Salesforce, follow these steps.
Use the following command to open the scratch project in the browser:
sf org:open -o <scratch org username>Replace
In the Salesforce setup menu, search for Static Resources and click the New button in the Static Resources tab.

Load the Syncfusion® scripts and styles as static files in a zip format, which you can obtain from the CRG.
In the static resource tab, provide a name for the static resource files, upload the zip file, and change the cache control to Public. Click Save button to add the static resources to your Salesforce project.

Adding CSP trusted sites
To ensure seamless integration and prevent content security policy issues, follow these steps.
In the Salesforce setup menu, search for CSP Trusted Sites and click the New Trusted Site button.

Enter the trusted site name and URL. For example, if the Syncfusion® static styles refer to https://fonts.googleapis.com, enter that URL as the trusted site URL.
Enable the following options to bypass CSP issues and click Save to apply the changes.
- Allow site for font-src
- Allow site for style-src

Creating a data model for appointments
To begin, navigate to the Object Manager in Salesforce and select Create followed by Custom Object.

In the custom object section, enter a meaningful label for your custom object. For this example, let’s name it SchedulerEvent. Once done, click Save to create the custom object.

Defining fields and relationships
Let’s configure the fields and relationships for the SchedulerEvent object. To do so, click the New button to create a new field.

- Set the data type for
StartTime. Choose DateTime as the data type for theStartTimefield. This field stores the starting time of each appointment.

- Provide a clear label for the
StartTimefield and click the Next button. Once you’ve reviewed the settings, click Save & New to proceed.

- Repeat the same steps to create the
EndTimefield, which stores the ending time of each appointment. Once you’ve reviewed the settings, click Save & New to proceed.

- Choose Checkbox as the data type for the
IsAllDayfield. This field is marked when an appointment is scheduled for the entire day.

- Assign an appropriate label, such as
IsAllDay, to the checkbox field. Click the Next button to review the settings and then click Save & New to proceed.

- Choose Text as the data type for the
Location/Recurrence Rule/Recurrence Id /Recurrence Exceptionfield to store the location field and recurrence rule for each appointment, as shown in the image. Click Next to review the settings and then click Save to proceed.

- Based on your specific requirements, you can add more fields to the
SchedulerEventobject by following the same steps.

Creating a Lightning web component
To integrate the JavaScript Scheduler into your Salesforce project, create a Lightning web component.
- In your Salesforce project, run the following command to generate a Lightning web component named
scheduler.
sf lightning:generate:component --type lwc -n scheduler -d force-app/main/default/lwc
- Open the
scheduler.js-meta.xmlfile located inforce-app/main/default/lwc/schedulerand modify the component definition to expose it in the Lightning App Builder. Here’s an example of the modified file.
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>57.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__AppPage">
<property name="height" label="Height" type="Integer" default="800" />
</targetConfig>
</targetConfigs>
</LightningComponentBundle>- Open the
scheduler.htmlfile located inforce-app/main/default/lwc/schedulerand add an element with a class name to append the scheduler. Here’s an example of the modified file.
<template>
<div class="syncfusionscheduler" lwc:dom="manual" style='width: 100%;'></div>
</template>- Open the
scheduler.jsfile located inforce-app/main/default/lwc/schedulerand implement the scheduler code in therenderedCallback()function. The static scripts and styles are loaded using theloadScriptandloadStyleimports. Here’s an example of the modified file.
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import { loadStyle, loadScript } from "lightning/platformResourceLoader";
import { createRecord, updateRecord, deleteRecord } from "lightning/uiRecordApi";
// Static resources
import schedulerFiles from "@salesforce/resourceUrl/syncfusionscheduler";
// Controllers
import getEvents from "@salesforce/apex/SchedulerData.getEvents";
function getEventsData(eventData) {
const data = eventData.events.map((a) => ({
Id: a.Id,
Subject: a.Name,
Location: a.Location__c,
StartTime: a.Start_Time__c,
EndTime: a.End_Time__c,
IsAllDay: a.IsAllDay__c,
RecurrenceRule: a.RecurrenceRule__c,
RecurrenceID: a.Recurrence_Id__c,
RecurrenceException: a.RecurrenceException__c
}));
return data;
}
export default class Scheduler extends LightningElement {
static delegatesFocus = true;
@api height;
schedulerInitialized = false;
renderedCallback() {
if (this.schedulerInitialized) {
return;
}
this.schedulerInitialized = true;
Promise.all([
loadScript(this, schedulerFiles + "/syncscheduler.js"),
loadStyle(this, schedulerFiles + "/syncscheduler.css")
])
.then(() => {
this.initializeUI();
})
.catch((error) => {
this.dispatchEvent(
new ShowToastEvent({
title: "Error loading scheduler",
message: error.message,
variant: "error"
})
);
});
}
initializeUI() {
const root = this.template.querySelector(".syncfusionscheduler");
root.style.height = this.height + "px";
const scheduleOptions = {
height: this.height + "px",
selectedDate: new Date(),
actionComplete: function (args) {
//To perform CRUD in salesforce backend
if (args.addedRecords && args.addedRecords.length > 0) {
var data = args.addedRecords[0];
var insert = {
apiName: "SchedulerEvent__c",
fields: {
Name: data.Subject,
Location__c: data.Location,
Start_Time__c: data.StartTime,
End_Time__c: data.EndTime,
IsAllDay__c: data.IsAllDay,
RecurrenceRule__c: data.RecurrenceRule,
Recurrence_Id__c: data.RecurrenceID,
RecurrenceException__c: data.RecurrenceException
}
};
createRecord(insert).then((res) => {
if (scheduleObj)
{
scheduleObj.eventSettings.dataSource[scheduleObj.eventSettings.dataSource.length - 1].Id = res.id;
scheduleObj.refreshEvents();
}
return { tid: res.id, ...res };
});
}
if (args.changedRecords && args.changedRecords.length > 0) {
var data = args.changedRecords[0];
var update = {
fields: {
Id: data.Id,
Name: data.Subject,
Location__c: data.Location,
Start_Time__c: data.StartTime,
End_Time__c: data.EndTime,
IsAllDay__c: data.IsAllDay,
RecurrenceRule__c: data.RecurrenceRule,
RecurrenceException__c: data.RecurrenceException,
Recurrence_Id__c: data.RecurrenceID
}
};
updateRecord(update).then(() => ({}));
}
if (args.deletedRecords && args.deletedRecords.length > 0) {
args.deletedRecords.forEach(event => {
deleteRecord(event.Id).then(() => ({}));
});
}
}
};
const scheduleObj = new ej.schedule.Schedule(scheduleOptions, root);
getEvents().then((data) => {
const eventData = getEventsData(data);
scheduleObj.eventSettings.dataSource = eventData;
scheduleObj.dataBind();
});
}
}Creating Apex class
The Apex class facilitates smooth interactions between your Lightning component and the data model. By following these steps, you can fetch and manipulate data from the SchedulerEvent custom object.
Use the following command to create an Apex class named SchedulerData.
sf apex:generate:class -n SchedulerData -d force-app/main/default/classes
Open the SchedulerData.cls file located in force-app/main/default/classes/SchedulerData.cls.
This fetches the event data from the Salesforce backend. Here’s an example of the modified file.
public with sharing class SchedulerData {
@RemoteAction
@AuraEnabled(cacheable=true)
public static Map<String, Object> getEvents() {
// fetching the Records via SOQL
List<SchedulerEvent__c> Events = new List<SchedulerEvent__c>();
Events = [SELECT Id, Name, Start_Time__c, End_Time__c, IsAllDay__c,
Location__c, RecurrenceRule__c, Recurrence_Id__c, RecurrenceException__c FROM SchedulerEvent__c];
Map<String, Object> result = new Map<String, Object>{'events' => Events };
return result;
}
}Pull scratch organization
To retrieve the changes made in the scratch organization and sync them with your local Salesforce project, use the following command.
sf project:retrieve:start -o <scratch org use name>Replace

Push scratch organization
To push the changes made in your local Salesforce project to the scratch organization, use the following command.
sf project:deploy:start -o <scratch org use name>Replace

Creating Lightning page
To display the JavaScript Scheduler on a Lightning page, follow these steps.
- In your scratch organization, search for
Lightning App Builderin the quick find setup, selectLightning App Builder, and click the New button.

- Choose App Page and click the Next button.

- Provide a label name for the app page and click the Next button. For example, you can name it
SyncfusionScheduler.

- Choose one Region and click the Finish button.

- In the Lightning App Builder, under the
Add Components Heresection, drag and drop the scheduler component. The scheduler will be rendered inside the content body. Click Save to activate the custom component.


- Activate the custom component named
SyncfusionSchedulerand click the Save button.

Launching scheduler in home page
To access the integrated JavaScript Scheduler on the home page, follow these steps.
Click the app launcher icon in Salesforce and search for SyncfusionScheduler, which was registered earlier in the Lightning App Builder.

Click the SyncfusionScheduler app, and the scheduler will load on the home page.

You can also explore our JavaScript Scheduler example to learn more about the Salesforce integration.