internet-explorerangular6calendly

Calendly Widget not working in IE (Angular App)


I am embedding a Calendly widget into a simple Angular application. It works in Chrome, Firefox, and Edge, but just shows a blank white box in IE.

The working url for the site is https://cei-demo.firebaseapp.com/schedule-an-appointment

I have tried using innerHTML to render the HTML code from the component and not in the template. I had the same problem.

calendly.component.html

<div class="my-5 p-3 container bg-white text-dark">
  <div class="calendly-inline-widget" data-url="https://calendly.com/test-cei" style="min-width:320px;height:700px;"></div>
</div>

index.html (right above the body tag)

<script type="text/javascript" src="https://assets.calendly.com/assets/external/widget.js"></script>

I would like the widget to display in all browsers.

Here is the code in response to Dmitry Pashkevich below:

component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-calendly',
  templateUrl: './calendly.component.html',
  styleUrls: ['./calendly.component.css']
})
export class CalendlyComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }
}

component.html

<div class="my-5 p-3 container bg-white text-dark">
  <div class="calendly-inline-widget" style="min-width:320px;height:580px;" data-auto-load="false">
</div> 

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Carbon Emery Insurance</title>
  <base href="/">
  <!-- reCaptcha -->
  <script src="https://www.google.com/recaptcha/api.js" async defer></script>

  <!-- Custom Fonts -->
  <link href="https://fonts.googleapis.com/css?family=Lato|Montserrat" rel="stylesheet">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="./assets/favicon.ico">

  <!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <!-- Font Awesome -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">

</head>
<body>
  <app-root></app-root>

  <!-- Bootstrap js -->
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  <script type="text/javascript" src="https://assets.calendly.com/assets/external/widget.js"></script>
  <script>
    Calendly.initInlineWidget({
    url: 'https://calendly.com/test-cei',
    parentElement: document.querySelector('.calendly-inline-widget'),
    });
  </script>
</body>
</html>

Solution

  • There is a special JavaScript API for invoking Calendly widgets from single-page applications in Angular, React, etc. With this API, you can control exactly when you want the widget to be initialized, instead of having it initialize upon page load.

    General instructions

    First, add a data-auto-load="false" attribute to the .calendly-inline-widget and remove the data-url attribute. So the element should look like this:

    <div class="calendly-inline-widget" style="min-width:320px;height:580px;" data-auto-load="false">
    

    Then, execute this code after when you want to initialize the Calendly widget:

    Calendly.initInlineWidget({
     url: 'https://calendly.com/test-cei',
     parentElement: document.querySelector('.calendly-inline-widget'),
    });
    

    More documentation here: Calendly Advanced embed options

    Wrapping it in an Angular component

    As outlined above, in order to dynamically create a Calendly embed widget, we need two things:

    1. Create a container element that the Calendly iframe will be rendered into by the Calendly Embed API
    2. Call the Calendly Embed API

    These two things combine perfectly in a Component:

    import { 
        Component, 
        NgModule, 
        VERSION, 
        ElementRef,
        ViewChild
    } from '@angular/core'
    
    @Component({
      selector: 'app-calendly-widget',
      template: `
            <div #container class="calendly-inline-widget" style="min-width:320px;height:580px;" data-auto-load="false"></div>
      `
    })
    export class CalendlyWidgetComponent {
        @ViewChild('container') container: ElementRef;
        
        ngOnInit() {
          Calendly.initInlineWidget({
            url: 'https://calendly.com/test-cei',
            parentElement: this.container.nativeElement
          });
        }
    

    The above code (TypeScript) defines a component that renders the container and immediately calls the Calendly Embed API upon initialization. We use Angular's @ViewChild to access the raw DOM element that the component renders.

    Here's a working demo: https://plnkr.co/edit/mpl6l8ifxc1amS611DMD?p=preview (note that it uses an older version of Angular than you're using, let me know if you have compatibility issues)