DEV Community

Cover image for Optimizing Productivity: Integrate Salesforce with JavaScript Scheduler
Jollen Moyani for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com on

Optimizing Productivity: Integrate Salesforce with JavaScript Scheduler

TL;DR: Learn the steps to integrate the JavaScript Scheduler into Salesforce. This includes creating and configuring a Salesforce project, authorizing it, adding static resources, creating a Lightning web component, and displaying the Scheduler on a Lightning page. Master your appointments effortlessly, unlocking enhanced productivity through this integration.

Syncfusion JavaScript Scheduler, or event calendar, is a fully featured event calendar component that helps users manage their time efficiently. It facilitates easy resource scheduling and rescheduling events or appointments through editor pop-ups, drag and drop, and resizing actions.

Salesforce is a cloud computing software-as-a-service (SaaS) company specializing in customer relationship management (CRM). It allows business users to use cloud technology to connect with their customers and partners better.

Let’s see how to integrate the JavaScript Scheduler into Salesforce for better productivity and streamline your scheduling processes.

Prerequisites

Configuring Salesforce

Follow these steps to configure the Salesforce to begin the integration process.

1.Log in with a Salesforce developer account. If you don’t have a Salesforce account, Sign up for one to access the necessary tools and resources for integration.
2.After a successful login, search for the Dev Hub option in the search box and select it. In the Dev Hub setup tab, ensure that the Enable Dev Hub option is enabled. If it’s not enabled, enable it to proceed further.

Refer to the following image.Enable the Enable Dev Hub option

Creating a Salesforce project

Let’s create a Salesforce project by following these steps:

1.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 salesforceApp
Enter fullscreen mode Exit fullscreen mode

2.Navigate to the base directory you created in the previous step and generate a Salesforce DX project using the following CLI command.

sfdx project:generate -n scheduler-salesforce-app
Enter fullscreen mode Exit fullscreen mode

Refer to the following image. Creating a Salesforce project

Authorizing salesforce project

Now, we need to authorize our Salesforce project by following these steps.

1.Run the following command in the browser to authorize your Salesforce project with your account.

sfdx org:login:web -d
Enter fullscreen mode Exit fullscreen mode

Authorize your Salesforce project with your account

2.Open the sfdx-project.json file located in the salesforceApp/scheduler-salesforce-app and update the sfdcLoginUrl with the domain URL of your Salesforce account. Update the sfdcLoginUrl in sfdx-project.json file

You can obtain the domain URL from the My Domain setup tab in Salesforce, as shown in the following image. Get domain URL in Salesforce settings

Create scratch org

Now, we need to create a scratch org project by running the following command. This will provide a new Salesforce environment for development and testing with the org id and username.

sfdx org:create:scratch -f config/project-scratch-def.json
Enter fullscreen mode Exit fullscreen mode

Create a scratch org project

Adding static resources

Then, integrate the Syncfusion scripts and styles as static resource files within Salesforce.

1.Use the following command to open the scratch project in the browser.

sfdx org:open -o <stratch org user name>
Enter fullscreen mode Exit fullscreen mode

Replace <scratch org username> with the username of your scratch org, which was generated during the creation process.

2.In the Salesforce setup menu, search for Static Resources and click on New in the Static Resources tab.Search for Static Resources and click on New in the Static Resources tab

3.Load the Syncfusion scripts and styles as static files in a zip format, which you can obtain from this Custom Resource Generator.

4.In the Static Resources tab, provide a name for the static resource files, upload the zip file, and change the cache control to Public. Click Save to add the static resources to your Salesforce project.Provide a name for the static resource files

Adding CSP-trusted sites

Follow these steps to ensure seamless integration of Salesforce with JavaScript Scheduler and prevent content security policy issues.

1.In the Salesforce setup menu, search for CSP Trusted Sites and click on New Trusted Site. Refer to the following image.Search for CSP Trusted Sites and click on New Trusted Site

2.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.

3.Enable the following options to bypass the CSP issues and click Save to apply the changes.

  • Allow site for font-src
  • Allow site for img-src
  • Allow site for style-src Enable font-src, img-src, style-src options to bypass CSP issues

Creating data model for appointments

1.First, navigate to the Object Manager tab in Salesforce and select Create, followed by Custom Object.Select Create, followed by Custom Object
2.In the custom object section, enter a meaningful label for your custom object. For this example, let’s name it SchedulerEvent. Once you’ve done this, click Save to create the custom object.Enter a meaningful label for your custom object

Defining fields and relationships

Let’s configure the fields and relationships for the SchedulerEvent object.

1.To do so, click New to create a new field (Say StartTime ).Click 'New' to create a new field (StartTime)

2.Set the data type for the StartTime field as DateTime. This field will store the starting time of each appointment.Set the Data Type for the StartTime field as DateTime

3.Provide a clear label for the StartTime field and click Next. Once you’ve reviewed the settings, click Save & New to proceed.Provide a clear label for the StartTime field and click Next

4.Repeat the same steps as above to create the EndTime field, which will store the ending time of each appointment. Once you’ve reviewed the settings, click Save & New to proceed.Create EndTime field

5.Create an IsAllDay field and choose Checkbox as the data type for it. This field will be marked when an appointment is scheduled for the entire day.Create an IsAllDay field and choose Checkbox as the data type for it

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

6.Choose Text as the data type for the Location/Recurrence Rule/Recurrence Id /Recurrence Exception field to store each appointment’s location and recurrence details. Click Next to review the settings, and then click Save to proceed.

Refer to the following images.Choose Text as the data type Label the location field Label the RecurrenceRule field

Following the steps outlined above, you can add more fields to the SchedulerEvent object based on your specific requirements.Created Fields & Relationships in the SchedulerEvent object

Creating a Lightning web component

In the Lightning version of Salesforce, we can create custom components and use them in the Lightning App Builder tool. This tool contains everything you need for a custom app, such as custom and standard objects and custom tabs.

Note: The Lightning Apps Builder tool isn’t available in Salesforce Classic.

Let’s create a Lightning web component to integrate the JavaScript Scheduler into your Salesforce project.

1.In your Salesforce project, run the following command to generate a Lightning web component named scheduler.

sfdx lightning:generate:component --type lwc -n scheduler -d force-app/main/default/lwc
Enter fullscreen mode Exit fullscreen mode

Generate a Lightning web component named scheduler

2.Open the scheduler.js-meta.xml file located at force-app/main/default/lwc/scheduler and modify the component definition to expose it in the Lightning App Builder. Here’s an example of the modified file.

[force-app/main/default/lwc/scheduler/scheduler.js-meta.xml]

<?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>
Enter fullscreen mode Exit fullscreen mode

3.Now, open the scheduler.html file located at force-app/main/default/lwc/scheduler and add an element with a class name to append the Syncfusion JavaScript Scheduler. Here’s an example of the modified file.

[force-app/main/default/lwc/scheduler/scheduler.html]

<template>
 <div class="syncfusionscheduler" lwc:dom="manual" style='width: 100%;'></div>
</template>
Enter fullscreen mode Exit fullscreen mode

4.Now, open the scheduler.js file located at force-app/main/default/lwc/scheduler and implement the Scheduler code in the renderedCallback function. The static scripts and styles are loaded using the loadScript and loadStyle imports. Here’s an example of the modified file.

[force-app/main/default/lwc/scheduler/scheduler.js]

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 the 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();
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

Creating Apex class

An Apex class facilitates smooth interactions between your Lightning component and the data model.

Follow these steps to fetch and manipulate data from the SchedulerEvent custom object effortlessly.

1.Use the following command to create an Apex class with the name SchedulerData .

sfdx apex:generate:class -n SchedulerData -d force-app/main/default/classes
Enter fullscreen mode Exit fullscreen mode

Create SchedulerData Apex class

2.Open the SchedulerData.cls file located at force-app/main/default/classes/SchedulerData.cls. This will fetch the event data from the salesforce backend. Here’s an example of the modified file.

[force-app/main/default/classes/SchedulerData.cls]

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;
   }
}
Enter fullscreen mode Exit fullscreen mode

Pull scratch org

To retrieve the changes made in the scratch org and sync them with your local Salesforce project, use the following command.

sfdx project:retrieve:start -o <scratch org use name>
Enter fullscreen mode Exit fullscreen mode

Replace <scratch org username> with the username of your scratch org.Pull scratch org

Push scratch org

To push the changes made in your local Salesforce project to the scratch org, use the following command.

sfdx project:deploy:start -o <scratch org use name>
Enter fullscreen mode Exit fullscreen mode

Replace <scratch org username> with the username of your scratch org.Push scratch org

Creating Lightning page

To display the JavaScript Scheduler on a Lightning page, follow these steps.

1.In your scratch org, search for Lightning App Builder in the quick find setup, select Lightning App Builder, and click New.Select Lightning App Builder

2.Then, choose App Page and click Next.Choose App Page and click Next

3.Provide a label name for the app page and click Next. Here, we’ll name it as SyncfusionScheduler.Provide a label name for the app page

4.Now, choose the One Region option and click Finish.Choose the One Region option

5.Then, drag and drop the Syncfusion JavaScript Scheduler component under the Add Components Here section in the Lightning App Builder. Now, the Scheduler will be rendered inside the content body. Refer to the following images.Drag and drop the Syncfusion JavaScript Scheduler under the Add Components Here sectionScheduler renders in content body

6.Activate the custom Scheduler component with the name SyncfusionScheduler and click Save.Activate the custom Scheduler component with the name SyncfusionScheduler

Launching the JavaScript Scheduler on the home page

To access the integrated JavaScript Scheduler on the Salesforce home page, follow these steps.

1.Click on the app launcher icon in Salesforce.
2.Search for SyncfusionScheduler, which was registered earlier in the Lightning App Builder.Search for SyncfusionScheduler
3.Click on the SyncfusionScheduler app, and the Scheduler will be loaded on the home page.

Integrating Syncfusion JavaScript Scheduler into Salesforce

Integrating Syncfusion JavaScript Scheduler into Salesforce

GitHub reference

You can check out the GitHub repository demo for the JavaScript Scheduler integration with Salesforce.

Summary

Thanks for reading! This blog provides a step-by-step guide for integrating the Syncfusion JavaScript Scheduler to manage your events and appointments within Salesforce efficiently. Try out the steps discussed in this blog post and enjoy hassle-free appointments and project management!

As always, you can contact us through our support forums, support portal, or feedback portal. We are always happy to assist you!

Related blogs

Top comments (0)