Ok, so here is what I came up with to create an iframe on the Data Item page from database data. Hopefully someone else finds this useful—but this is my first experience with Wix, so all caveats apply. I have not really tested this yet either.
I had to edit this file to remove links to work around the bug I mention above.
Specifically I am including mixcloud widgets which look like this:
<iframe width="100%"
height="120"
src="REMOVEDSINCEICANTPOSTLINKS"
frameborder="0" ></iframe>
That encoded fragment, /spartacus/party-time
comes from the database.
So first of all, I created Dynamic Pages called MixCloudCasts
This seems to give me a Dynamic List Page which lists all the mixcloud items, and a Dynamic Item Page which displays one item.
I created a Collection (database table) to go along with it. I think I created it from the Dynamic Page dialogue, though I might be mistaken. It has a field “key”, which contains the fragment “/spartacus/party-time”, which is destined for the query string in the iframe src.
So then I created a custom element on the Dynamic Item page via Add => Embed => Custom Embeds => Custom Element. In the Custom Element editor that comes up, I used these settings:
Element Settings = Velo File
Select one of your Velo Files = mixcloudPlayer.js
TagName = mixcloud-player
The widget itself is a standard Custom Element. The editor for this is difficult to find—there’s an icon with curly braces on the left “{}”, then “Public and Backend” => “Public” => “Custom Elements”. My code seems to be there, in the file “mixcloudPlayer.js”.
When I click on it, my code appears in a tab at the bottom of the screen. I replaced what was there with this:
const BASE_URL = "HTTPSMIXCLOUDCOM/widget/iframe/"
const createIFrame = (key) => {
if (!key) {
const div = document.createElement('div');
// I should do a better job of this
div.textContent = "LOADING...";
return div;
}
const src = BASE_URL + "?hide_cover=1&light=1&feed=" + encodeURIComponent(key);
const iframeElement = document.createElement('iframe');
iframeElement.width = "100%"
iframeElement.height = "120"
iframeElement.src = src;
iframeElement.frameborder = "0"
iframeElement. id = "mixcloud-iframe"
return iframeElement;
};
class MixCloudPlayerElement extends HTMLElement {
constructor() {
super();
console.log(DEBUG_TEXT);
}
static get observedAttributes() {
return ['key'];
}
get key() {
return this.getAttribute('key');
}
set key(newValue) {
this.setAttribute('key', newValue);
}
connectedCallback() {
const el = createIFrame(this.key)
this.appendChild(el);
}
}
customElements.define('mixcloud-player', MixCloudPlayerElement);
When the “key” attribute is set, it will render the iframe from that.
So to get the data to the component, at the bottom of the page I have an editor which says “MixCloudCasts (Slug)” which seems to be my Data Item page initialization javascript. I replaced it with this:
$w.onReady(function () {
$w("#dynamicDataset").onReady(() => {
let currentCloudCast = $w("#dynamicDataset").getCurrentItem();
$w('#mixCloudPlayer').setAttribute('key', currentCloudCast.key);
});
});
It appears you need to nest the onReady commands, as per this post. The ambient dataset (a dataset seems to be the bridge that connects you to the database) is accessible via $w(“#dynamicDataSet”), and I use that to get the current item. Then I send the data item to the player, which I find via $(“#mixCloudPlayer”).
This seems to work when I preview it. But I’d be interested to know if there’s anything I missed.