How to create Calendar in LWC and show Opportunity Data on it.

Posted on August 29, 2020 Post Thumbnail

Hi Trailblazers, In this post, I'm going to create a Calendar in Lightning Web Component and show Opportunities records on it by their CloseDate.

Youtube video for this blog post.

https://youtu.be/sagGaG1DkfY

Why Opportunities on Calendar?

It's makes easy to find opportunities for current month and provides a Visualised experience.

Workflow

1. First We'll Search a third party JS Library for generating Calendar.

2. Then We'll Load that JS Library in our LWC.

3. We'll modify UI.

4. We'll load data from Salesforce and get in LWC.

6. We'll create JS Object and We'll push returned data in JS Object.

What you'll learn from this blog post?

1. You'll learn, how to retrieve Data from Salesforce Database in LWC.

2. You'll learn, how to use third party JS Library in LWC.

Let's Start.

1. I'll consider you know basics of LWC and Project Structure in Salesforce CLI.

2. Open your Existing Project in VS Code.

3. Create new LWC with name of opportunityVisualizer, Run following command.

sfdx force:lightning:component:create --type lwc -n opportunityVisualizer -d force-app/main/default/lwc
Just created opportunityVisualizer LWC.

Just created opportunityVisualizer LWC.

4. Let's search a JS Library for Calendar.

a. Open your browser and search Full Calendar

b. Click on the first search result.

Click on the first search result.

c. Click on Get Started.

Click on Get Started.

d. From Get Started Page Download zip files.

If you have trouble, Just download the library from here.

https://drive.google.com/file/d/1d7z45sHFghKbk5phx5y5CI6CGv9tvJda/view?usp=sharing

 

From Get Started Page Download zip files.

e. Create a new static Resource in Salesforce FullCalendarJS.

f. Upload it into Static Resource.

5. Now we'll load these files in JS of Our LWC.

import { loadScript, loadStyle } from 'lightning/platformResourceLoader';

Importing loadScript and loadStyle (methods) from lightning platformResourceLoader.

import FullCalendarJS from '@salesforce/resourceUrl/FullCalendarJS';

Importing folder from StaticResource.

We'll promise on loadScript to load all files.

 Promise.all([
     loadScript(this, FullCalendarJS + '/FullCalendarJS/jquery.min.js'),
      loadScript(this, FullCalendarJS + '/FullCalendarJS/moment.min.js'),
      loadScript(this, FullCalendarJS + '/FullCalendarJS/fullcalendar.min.js'),
      loadStyle(this, FullCalendarJS + '/FullCalendarJS/fullcalendar.min.css'),,
      // loadStyle(this, FullCalendarJS + '/fullcalendar.print.min.css')
    ])
    .then(() => {
      // Initialise the calendar configuration
      this.getTasks();
    })
    .catch(error => {
      // eslint-disable-next-line no-console
      console.error({
        message: 'Error occured on FullCalendarJS',
        error
      });
    })

6. Modify the UI and Add our Logo.

opportunityVisualizer.html

<template>
  <div class="slds-box outerPart">
    <img width=25% src={SfLogo}>
    <p class="slds-m-bottom_small">Opportunity Visualizer</p>
    <!--lightning-button variant="brand" name="verifyMail" label="Sync Salesforce Tasks" onclick​={initialiseFullCalendarJs}></lightning-button-->
    <div style="background:#ffffff;" class="slds-grid slds-m-top_medium">
      <div id="calendar" class="fullcalendarjs"></div>
    </div>
  </div>
</template>

You need to add an Image in static resource for it.

opportunityVisualizer.css

.outerPart
{
    background-color:rgba(138, 177, 159, 0.685);
}
div{
    text-align: center;
}
p{
    font-size: 200%;
    color:white;
}

7. Now Load Opportunities from Salesforce.

a. Let's create a class in Apex and a Method to gets Opportunities.

global with sharing class oppoCloseDate {
    @AuraEnabled
    global static string getOppo()
    {
        list<opportunity> oppoList = new list<opportunity>();
        oppoList = [ SELECT Id, Name, closeDate FROM opportunity];
        return JSON.serialize(oppoList); 
    }
}

b. We'll call this method after successfully promising from JS.

c. Here's the final JS code.

opportunityVisualizer.js

import { LightningElement, track } from 'lwc';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import FullCalendarJS from '@salesforce/resourceUrl/FullCalendarJS';
import getOppo from '@salesforce/apex/oppoCloseDate.getOppo';
import heySfLogo from '@salesforce/resourceUrl/heySfLogo';
/**
 * @description Full Calendar JS - Lightning Web Components
 */
export default class opportunityVisualizer extends LightningElement {
//  @track eventData ;
  @track returnedOppo = [] ;
  @track finalOppo = [] ;
  SfLogo = heySfLogo ;

  renderedCallback() {
    Promise.all([
      loadScript(this, FullCalendarJS + '/FullCalendarJS/jquery.min.js'),
      loadScript(this, FullCalendarJS + '/FullCalendarJS/moment.min.js'),
      loadScript(this, FullCalendarJS + '/FullCalendarJS/fullcalendar.min.js'),
      loadStyle(this, FullCalendarJS + '/FullCalendarJS/fullcalendar.min.css'),
      // loadStyle(this, FullCalendarJS + '/fullcalendar.print.min.css')
    ])
    .then(() => {
      // Initialise the calendar configuration
      this.getTasks();
    })
    .catch(error => {
      // eslint-disable-next-line no-console
      console.error({
        message: 'Not Loading FullCalendarJS',
        error
      });
    })
  }
  initialiseFullCalendarJs() {
    var str = window.location.href;
    var pos = str.indexOf(".com/");
    var last = pos + 4;
    var tDomain = str.slice(0,last);
    for(var i = 0 ; i < this.returnedOppo.length ; i++)
    {
      this.finalOppo.push({
        start : this.returnedOppo[i].CloseDate,
        title : this.returnedOppo[i].Name,
        url : tDomain+'/lightning/r/Opportunity/'+this.returnedOppo[i].Id+'/view'
    });
    }
    const ele = this.template.querySelector('div.fullcalendarjs');
    // eslint-disable-next-line no-undef
    $(ele).fullCalendar({
      header: {
          left: 'prev,next today',
          center: 'title',
          right: 'month,basicWeek,basicDay'
      },
     // defaultDate: '2020-03-12',
      defaultDate: new Date(), // default day is today
      navLinks: true, // can click day/week names to navigate views
      editable: true,
      eventLimit: true, // allow "more" link when too many events
      events : this.finalOppo
    });
  }
  getTasks(){
    getOppo()
        .then(result =>{   
           this.returnedOppo = JSON.parse(result);
            this.initialiseFullCalendarJs();
            this.error = undefined;
        })
        .catch(error => {
            this.error = error;
            this.outputResult = undefined;
        });
  }
}

In above code if you find any difficulty, Please let me know.

It's too hard you explain each line.

opportunityVisualizer.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>49.0</apiVersion>
    <isExposed>true</isExposed>
     <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>
</LightningComponentBundle>

d. Push it into your org using Username like this.

sfdx force:source:deploy -p force-app -u [email protected]

e. Open your org and check it in Custom Components.

Open your org and check it in Custom Components.

f. Add it on your home page and save it.

Add it on your home page and save it.

This is how it looks.

Try it out and Let me know if you find any difficulty.

Youtube video for this blog post.

https://youtu.be/sagGaG1DkfY

Thanks for Reading,

Comment down for any questions.

You can also follow me on Twitter 


9598
19

Tags: #salesforce #lwc

Comments

  • Shivendra TechSter Avatar
    Shivendra TechSter - 1 year ago
    Nice post

    Asif Ali Avatar
    Asif Ali - 1 year ago
    Thanks

  • Shubham Bhardwaj Avatar
    Shubham Bhardwaj - 1 year ago
    Awesome bhai sure I will give it a try

    Asif Ali Avatar
    Asif Ali - 1 year ago
    Thanks Shubham, Try it.

  • Prateek Khanna Avatar
    Prateek Khanna - 1 year ago
    Great Post Asif !!

    Shivendra TechSter Avatar
    Shivendra TechSter - 1 year ago
    Thanks Prateek

  • Salesforce Starter Avatar
    Salesforce Starter - 1 year ago
    Great Post, just one question, how can I change the theme in the calendar? Thanks!

  • Fathi Avatar
    Fathi - 1 year ago
    Hi Ali, This is a supper post, I'm trying to do it but I'm getting errors on the static resources, which I can't find. giving me a 404 error. loadScript(this, FullCalendarJS + '/jquery.min.js'), loadScript(this, FullCalendarJS + '/moment.min.js'), loadScript(this, FullCalendarJS + '/fullCalendar.min.js'), loadStyle(this, FullCalendarJS + '/fullCalendar.min.css'), while I loaded the ZIP Download: fullcalendar-5.4.0.zip Thnk you for your help Fathi

    Asif Ali Avatar
    Asif Ali - 1 year ago
    Fathi, Please try this zip file, https://drive.google.com/file/d/1d7z45sHFghKbk5phx5y5CI6CGv9tvJda/view?usp=sharing delete that static resource and create new FullCalendarJS Case sensitive. Let me know if it works for you. Regards, Asif

  • Jay stahlman Avatar
    Jay stahlman - 1 year ago
    I want use navigatemixin to launch view page upon event click. I receive function not defined error. This function works fine when called from a button. Any advice?

    Asif Ali Avatar
    Asif Ali - 1 year ago
    Make sure you pass the Event in the parameter. function(event) { };

  • Shubham joshi Avatar
    Shubham joshi - 1 year ago
    Hi Asif Want to perform navigation to launch view page upon event click

  • Shubham Avatar
    Shubham - 10 months ago
    I have implemented the above solution with a custom object but my data is not populated on the calendar.

    Asif Ali Avatar
    Asif Ali - 9 months ago
    Make sure you're creating array of object correctly

  • Ayush Avatar
    Ayush - 9 months ago
    I'm getting error Error during LWC component constructor phase: [heySfLogo is not defined]. Help me on this

    Asif Ali Avatar
    Asif Ali - 9 months ago
    Comment this line, This is for logo only or add a file in static resource/

  • Lidia GC Avatar
    Lidia GC - 8 months ago
    Hi Asif, thank you, one question, the file opportunityVisualizer.css where should be located?

    Asif Ali Avatar
    Asif Ali - 7 months ago
    In the same folder,

  • Fabien Braconnier Avatar
    Fabien Braconnier - 6 months ago
    Hello Asif, Thanks for this post, will try it for sure. The video on youtube is private how can i acces it?

Your message is required.

Get notified of new posts