I have sent the below document as a PDF already to some people here, but I paste it here for you. Bit less readable, but this should answer your question. It´s about Google Sheets, but it works the same for everything you want to do in the html-component: “wait for it to fully load”.
The Wix HTML-component and Google Sheets
Abstract
This article describes how to display a different Google Sheet (per Item) on every Wix Dynamic
page. The data for the sheet is read from the database and then displayed inside the Wix
HTML-component.
The problem
Let us assume that we have a Dynamic page with an html-component called
#ifrGoogleSheetsDocs.
Also, after having the Google sheet published, we would have (after a bit of tweaking, more on
that later) a code snippet to it like this;
At first, I sent the Google code for that sheet to the html-component using this HTML inside
the component´s properties:
using, inside the Wix Page, this to trigger it;
$w("#ifrGoogleSheetsDocs").postMessage(txtMessage);
$w("#ifrGoogleSheetsDocs").show();
txtMessage held the Google Sheets snippet, read from the database. The html-component was
HiddenOnLoad, so the .Show(), well, … shows it.
The problem was: this worked fine in Preview Mode, but in Publish mode, it did not show the
Sheet at all.
The cause
Although the above code was inside a $w.onload, it turned out that this onLoad only is valid for
the main page, NOT the html-components inside it.
When your page is run and it encounters the html-component, a separate process is spawned,
completely asynchronous from the main page. So what then happens is this:
1: the main page with all the code does NOT wait for the html-component to load, it just goes
on with the next instruction, while
2: in another process, the html-component is loaded, the html is parsed, the DOM populated,
the html executed and THEN the component is ready.
And that moment may come later then the main page encounters the above .postMessage. So,
the main page sends a message (holding the Google Sheet html) earlier than the htmlcomponent
is ready. The result is that the main page sends a message to the component that
doesn´t listen yet and therefore the html is not received, thus not displayed.
Preview vs. Publish
But why did it work in Preview mode and not in Publish Mode? Well, have you never noticed
that when you press Preview, the screen doesn´t flicker and the page is not reloaded? That is
because, if you look at the Wix code inside your browser, Preview Mode is just a CSS-class that
turns off a couple of controls when in Editing mode.
This means, the html-component was already loaded (you have been looking at it for half an
hour while in Editing Mode) and thus it was more than ready to receive the message. But in
Publish Mode, everything has to be loaded fresh, and there we run into our problem.
The solution
All Wix examples regarding the html-component let the Main program start a conversation and
then the html-component answers. What we want is to turn it around: that the htmlcomponent
starts the conversation and the main program listens and answers back.
So, we have to roll our own “onReady” for the html-component. Only when it is ready to
receive a message, then we send the Google Sheets snippet. So how do we do that?
Well, it goes like this:
1) when the component is ready (the BODY onLoad = ... inside its HTML), send a message to
the main program that it is so, using window.onmessage inside the html-component´s html;
2) the main program must wait until it receives a message from the component (using the
.onMessage from the html-component). Only then will it send the Google Sheets string
using .postmessage
3) the html inside the component must now put the received code into a block (like a DIV) to
be displayed using .innerHtml.
4) done
The code
This goes into the html-component:
Note: the “LoadOK” message could be anything, like “You´re holding it wrong” or
“Done”. It´s not about WHAT the component sends, it´s about THAT it sends.
The white background color is of course up to you to set differently, or not at
all.
This goes into the main program:
datasetname and fieldname (and maybe ifrGoogleSheetsDocs) should be replaced by your own
names.
let urlMessage = $w('#datasetname').getCurrentItem().fieldname;
$w("#ifrGoogleSheetsDocs").onMessage( (event) => {
$w("#ifrGoogleSheetsDocs").postMessage(urlMessage);
});
Google Sheets tweaks
Google Sheets gives us a code snippet which we can paste into a page. Thing is, if you use it
as as, it shows a sheets with tabs and a bottom bar. I wanted to get rid of that and only show
the sheet itself. In Google Sheets documentation I found these settings:
•gid=1674242611 - This is the sheet ID
•range=A1:B14 - The range you want to display.
•widget=false - If false, there's no sheet tab displayed at the bottom
•headers=false - Row numbers and column letters are not displayed.
•chrome=false - Title and footer is not displayed.
Also, width and height can be set to a percentage. If you want to get rid of the gridlines, you
will have to set that inside the sheet itself.
Written by: girizano@gmail.com
All statements made are mine and not endorsed or verified by Wix.