1

Handsontable is a neat looking spreadsheet plugin for Javascript. I can't get even the quick start to display in an LWC component. It seems to initialize but the data never shows up. As far as I can tell, I'm following the 3rd party library instructions for LWC. I've looked through the Handsontable docs, worked with support and a common solution is to call render() after a timeout. I tried 150ms, 300ms, 5000ms but that doesn't seem to make a difference. I don't see any errors, just a rendered empty table in the source. Can anyone assist? I'm happy with any spreadsheet type grid if there's one you have working.

Here's where I am:

  1. Use the Handsontable quick start as the target goal: https://handsontable.com/docs/7.1.0/tutorial-quick-start.html
  2. Download LWC Recipes - my code is modeled very carefully after the libsD3 example seen here https://github.com/trailheadapps/lwc-recipes/tree/master/force-app/main/default/lwc/libsD3
  3. Modify the 3rd party library examples and make a new libsSheet LWC component
  4. Uploaded handsontable Vanilla JS zip file as a static resource (label: "handsontable")
  5. Wrote this code:
<!-- libsSheet.html -->
<template>
    <lightning-card title="My Sheet" icon-name="custom:custom19">
        <div class="slds-m-around_medium">
            <div id="hot" class="hot" lwc:dom="manual" style="height:300px;width:800px;"></div>
        </div>
    </lightning-card>
</template>
//libsSheet.js
import { LightningElement, track,api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import hands from '@salesforce/resourceUrl/handsontable';

export default class LibsSheet extends LightningElement {
    sheetInitialized = false;
    renderedCallback() {
        if (this.sheetInitialized) {
            return;
        }
        this.sheetInitialized = true;

        Promise.all([
            loadScript(this, hands + '/handsontable-master/dist/handsontable.full.min.js'),
            loadStyle(this, hands + '/handsontable-master/dist/handsontable.full.min.css')
        ]).then(() => {
            this.initializeSheet();
    })
    .catch(error => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error loading Sheets',
                    message: error.message,
                    variant: 'error'
                })
            );
    });
    }

    initializeSheet() {
        var cmp = this.template.querySelector('.hot');
        var data =  [
                ['', 'Maserati', 'Mazda', 'Mercedes', 'Mini', 'Mitsubishi'],
                ['2009', 0, 2941, 4303, 354, 5814],
                ['2010', 3, 2905, 2867, 412, 5284],
                ['2011', 4, 2517, 4822, 552, 6127],
                ['2012', 2, 2422, 5399, 776, 4151]
            ];

        this.hsheet = new Handsontable(cmp, {
            data: data,
            colHeaders: true,
            rowHeaders: true,
            contextMenu: true,
            licenseKey: 'non-commercial-and-evaluation'

        });

        setTimeout(() => {
            this.hsheet.render();
        },1000);
    }
}
<!-- libsSheet.js-meta.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>46.0</apiVersion>
<description>Libs Sheet</description>
<masterLabel>Libs Sheet</masterLabel>
<isExposed>true</isExposed>
<targets>
    <target>lightning__AppPage</target>
    <target>lightning__RecordPage</target>
    <target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
  • 1
    Have you tested the library in the Locker Service console? – Robs Jul 18 at 15:43
  • No, but I will start using that. Thanks Robs – sfsf610 Jul 18 at 16:14
  • @Robs - I tried it, connected it to my org, but I get an error pretty much no matter what I have in my code- so I'm not sure how much it will help. The error is truncated in the "Locker On" column and I can't see the whole error. Is there any way to see the full in that Locker Service Console? Thanks – sfsf610 Jul 18 at 21:07
3

This library is trying to break out of the shadow dom which is prevented by lockerservice. So i would consider it as non LWC Compliant which means only available in aura (could still fail due to lockerservice on a different line) or lockerservice workarounds like aura component max version 39, lightning:container app or iframed vf page

  • Thank you - much appreciated! So let's say I want to look for an LWC compliant 3rd party library before I use a workaround. In the future, how can I see whether it has shadow DOM violations? I didn't see anything that made this clear in the Chrome dev tools or console. Will I always need to go through third party code? Is there something specific I should look for? (anything in addition to this locker console mentioned above) – sfsf610 Jul 18 at 16:14
  • i guess unfortunately no which is the general pain point of 3rd party libs and lockerservice (except they are explicitly developed by a sfdc dev which is aware of those restrictions and e. g. claim the compability explicitly). That are most of the times restrictions which comes from sfdc. So in your example it would work fine outside of sfdc and normal Web Components (it even should work with oss LWC) - the limitation is due to lockerservice. Therefore i don`t think you can generally know in advance if a lib will work or not. Only that the chance is lower if its working on the dom directly – Renji-xD Jul 18 at 16:38
  • For lockerservice console: it is good if you want to know what apis are supported and not - but that means of course you would already again know what the library is doing etc so not helpful to check if a lib will work or not. Also its more about general apis sitting on the window / document object rather then real dom interaction / encapsulation concepts – Renji-xD Jul 18 at 16:47
  • Thanks all - Then I ask Salesforce to please consider the ability to see a clear error of a violation of the locker service somewhere. Console log would be nice. – sfsf610 Jul 18 at 19:57
  • Got the grid working in Visualforce in about 20 minutes. I'll save this as an LWC project for another day. I was really hoping to use LWC but I'll have to wait. Fortunately, I have a workaround. – sfsf610 Jul 18 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.