How do I insert an HTML Script embed into React? - javascript

I am trying to get an eCommerce html script embed to work in React, by having it render from a component.
An example below:
<div data-embed="store">
<script type="application/json">
{"some json text"}
</script>
</div>
<script async src="https://website.com/loader.js"></script>
From what I have been able to gather, I can use the useEffect hook, but have not been able to get it to work correctly.

You can do this in useEffect by creating a script element, adding the src and async attribute and appening it to the document body. You would then have the imported JS available globally.
EDIT:
The same can be applied to JSON with exception of having to load it in manually.
const [json, setJson] = useState(null);
useEffect(() => {
const script = document.createElement('script');
script.src = "https://website.com/loader.js";
script.async = true;
document.body.appendChild(script);
// json
const jsonScript = document.createElement('script');
jsonScript.innerHTML = `
{
"greeting": "hello"
}
`;
jsonScript.id = 'json';
jsonScript.type = 'application/json';
document.body.appendChild(jsonScript);
setJson(JSON.parse(document.getElementById('json').innerHTML));
}, []);

Related

Snabbdom - Not able to load javascript file into snabbdom project

I want to embed a web-component based javascript file into the snabbdom based project but not able to load it into the project.
Also not able to find that particular javascript file in the dist folder after building the project.
const view = (state, {updateState}) => {
function AddLibrary(urlOfTheLibrary) {
console.log("add librar",urlOfTheLibrary);
const script = document.createElement('script');
script.src = urlOfTheLibrary;
document.head.appendChild(script);
}
return (
<div>
<div>Hello</div>
<sg-bar hook-init={AddLibrary("/sg-bar.js")}></sg-bar>
</div>
);
};

Trying to add a Motoko snippet to an edX page and only the HTML is being parsed

This is the current snippet that is not running any of the Motoko scripts in edX when inserted onto a page.
All that is being parsed currently is the Html part.
Are the scripts pointing to the correct file locations or have I done something wrong during the upload process?
<div id="counter" class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-motoko hljs" data-lang="motoko">actor Counter {
​
var value = 0;
​
public func inc() : async Nat {
value += 1;
return value;
};
}</code></pre>
</div>
</div>
​
​
<!-- Start of dfinity Zendesk Widget script -->
<script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=53121947-c10a-484c-b99b-f89a9fb6f63e"> </script>
<!-- End of dfinity Zendesk Widget script -->
<script async type="text/javascript" src="https://courses.edx.org/asset-v1:DFINITY+IC001+3T2021a+type#asset+block#behavior.js"></script>
<script async type="text/javascript" src="https://courses.edx.org/asset-v1:DFINITY+IC001+3T2021a+type#asset+block#highlight.bundle.js"></script>
​
<script type="text/javascript" src="https://courses.edx.org/asset-v1:DFINITY+IC001+3T2021a+type#asset+block#run_repl.js"></script>
​
<script type="module">
import {CodeJar} from 'https://cdn.jsdelivr.net/npm/codejar#3.2.3/codejar.min.js';
import {withLineNumbers} from 'https://cdn.jsdelivr.net/npm/codejar#3.2.3/linenumbers.js';
window.CodeJar = CodeJar;
window.withLineNumbers = withLineNumbers;
</script>
<script type="module">
import {CodeJar} from 'https://medv.io/codejar/codejar.js'
</script>
<script type="text/javascript">
async function addPackage(name, repo, version, dir) {
const meta_url = `https://data.jsdelivr.com/v1/package/gh/${repo}#${version}/flat`;
const base_url = `https://cdn.jsdelivr.net/gh/${repo}#${version}`;
const response = await fetch(meta_url);
const json = await response.json()
const promises = [];
const fetchedFiles = [];
for (const f of json.files) {
if (f.name.startsWith(`/${dir}/`) && /\.mo$/.test(f.name)) {
const promise = (async () => {
const content = await (await fetch(base_url + f.name)).text();
const stripped = name + f.name.slice(dir.length + 1);
fetchedFiles.push(stripped);
Motoko.saveFile(stripped, content);
})();
promises.push(promise);
}
}
Promise.all(promises).then(() => {
Motoko.addPackage(name, name + '/');
console.log(`Loaded motoko library "${name}"`);
changeCodeBlock(); // from run_repl.js
});
}
function loadBase() {
addPackage('base', 'dfinity/motoko-base', 'dfx-0.8.4', 'src');
}
</script>
​
<script async src="https://courses.edx.org/asset-v1:DFINITY+IC001+3T2021a+type#asset+block#moc-interpreter-0.6.20.js" onload="loadBase()"></script>
after looking through your code there's a few missing pieces that may solve the problem.
The hightjs script is missing, which you can either attach to the head or body. You can choose to include their stylesheet or not.
https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/styles/default.min.css
https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js
The run_repl here (https://courses.edx.org/asset-v1:DFINITY+IC001+3T2021a+type#asset+block#run_repl.js) has unexpected characters (backslashes) such that the file is not truly working. Please copy and replicate from here: https://github.com/dfinity/antora-sdk/blob/master/src/js/vendor/run_repl.js
There's some styling added inside Dfinity's website, which has been referenced. I've pulled it into a stylesheet on this replit project. Take a look!
https://replit.com/#Sue-AnnAnn/Motoko-highlight#index.html
There is an easier solution now!
https://embed.smartcontracts.org/motoko/g/3oBbKveNbudpGgKMb2A5wADMcv3U6CDvxfjKMvASfcmkuXEk9j7UtFCn2DpHrUVJ3dSJYEMu2bW54vZRiPhYk4MDgdXkQhHwt1HhmcLi3GpCowBeaYus4BUpMZNDMLKezqBwcMg7EXFbVvNYR5xp57dViryE9uawnFjkuZacyor5jp?lines=10
Copy the iframe code and embed it into a raw HTML page on EDX.

export plotly as self-contained html in JavaScript

In JavaScript, how to export plotly plot as a self-contained html file? Just like in R, we can use saveWidget function. How to do it with JavaScript?
Edit
I tried to use
var a = document.body.appendChild(
document.createElement("a")
);
a.download = "export.html";
a.href = "data:text/html," + document.getElementById("myDiv").innerHTML;
a.click();
But it does work well because it loses all the event, etc.
https://codepen.io/anon/pen/XqZqWX
You can download plotly.js and then call Plotly.newPlot method.
Here are step details.
Get plotly script text
async function getPlotlyScript() {
// fetch
const plotlyRes = await fetch('https://cdn.plot.ly/plotly-latest.js')
// get response as text
return await plotlyRes.text()
}
Get plotly chart data
We need to pass the current chart state in Plot.newPlot method. If the chart data and layout are not controlled by your code, don't worry. The DOM element where plotly builds the chart contains data and layout.
function getChartState () {
const el = document.getElementById('your plotly container id')
return {
data: el.data, // current data
layout: el.layout // current layout
}
}
Compose HTML
Now we have everything to compose our HTML. Don't forget to:
add charset="utf-8" because plotly script has special characters.
escape closing script tag to make browser consider it as a string, not as a tag
async function getHtml() {
const plotlyModuleText = await getPlotlyScript()
const state = getChartState()
return `
<head>
<meta charset="utf-8" />
</head>
<script type="text/javascript">
${plotlyModuleText}
<\/script>
<div id="plotly-output"></div>
<script type="text/javascript">
Plotly.newPlot(
'plotly-output',
${JSON.stringify(state.data)},
${JSON.stringify(state.layout)}
)
<\/script>
`
}
Download HTML document
async function exportToHtml () {
// Create URL
const blob = new Blob([await getHtml()], { type: 'text/html' })
const url = URL.createObjectURL(blob)
// Create downloader
const downloader = document.createElement('a')
downloader.href = url
downloader.download = 'export.html'
// Trigger click
downloader.click()
// Clean up
URL.revokeObjectURL(url)
}
exportToHtml()

Javascript trouble in dynamically call another class in other js file

I'm trying to make a javascript function to call another .js file like this:
scriptCaller.js
function callScript(file){
var script = document.createElement('script');
script.id = file;
script.type = 'text/javascript';
script.async = true;
script.src = "script/"+file+".js";
document.getElementById('scriptSection').appendChild(script);
}
Then I create some class to be called by that script in other file:
divGenerator.js
function divGenerator(){
var self = this;
var div = document.createElement('div');
this.tag = function(){
return div;
}
/*and some other function to style the div*/
}
Then i make the main file to be executed:
main.js
function build(){
callScript('divGenerator');
}
function main(){
var test = new divGenerator();
/*execute some function to style the div*/
document.getElementById('htmlSection').appendChild(script);
}
All the three file will be called in a HTML files that will execute the main function:
myPage.html
<html>
<head>
<title>myPage</title>
</head>
<script src="scriptCaller.js"></script>
<script src="main.js"></script>
<body>
<div id="htmlSection"></div>
<div id="scriptSection"></div>
</body>
</html>
<script>build();</script>
<script>main();</script>
If I correct it should display the styled div, but what I got is an error that said:
TypeError: divGenerator is not a constructor[Learn More]
But, when I move the divGenerator() class to myPage.html it works fine. Any idea to solve this problem?
You need to add scriptCaller.js and divGenerator.js to your html script element.
<html>
<head>
<title>myPage</title>
</head>
<script src="scriptCaller.js"></script>
<script src="main.js"></script>
<script src="scriptCaller.js"></script>
<script src="divGenerator.js"></script>
<body>
<div id="htmlSection"></div>
<div id="scriptSection"></div>
</body>
</html>
<script>build();</script>
<script>main();</script>
You have couple of problems in your code. First of all, do not assign id to script element same as the "exported" global constructor name. You need to remember that anything with id attribute (and name) automatically gets exposed as global variable on window object. It means that divGenerator in your case is going to be reference to HTMLScriptElement, not a constructor function.
Second problem is related to timing, since you are loading script with async attribute. This is good, but you need to realise that in this case you can't expect that script will be loaded when you call main after build(). I would suggest to wrap script creation into promise:
function callScript(file){
return new Promise(function(resolve) {
var script = document.createElement('script');
script.id = 'script-' + file; // Note different id
script.async = true;
script.src = "script/" + file + ".js";
script.onload = resolve
document.getElementById('scriptSection').appendChild(script);
})
}
and use it like this:
<script>
build().then(function() {
main();
})
</script>

Placing Amazon Banner | Angular V4

I'm placing an Amazon banner inside an angular material 2 card.But the problem is that it is not rendering.It shows empty div.What could be the reason.Below is the code showing how I did it.
<md-card class="full-width full-height border-box ">
<div class="adv">
<script type="text/javascript" language="javascript">
var aax_size = '728x90';
var aax_pubname = 'XXXXXXXXXXX';
var aax_src = '302';
</script>
<script type="text/javascript" language="javascript" src="http://c.amazon-adsystem.com/aax2/assoc.js"></script>
</div>
</md-card>
I also tried to to bind it using property binding
<span [innerHTML]="advertisement()"></span>
advertisement(){
return `<div class="adv">
<script type="text/javascript" language="javascript">
var aax_size = '728x90';
var aax_pubname = 'XXXXXXXXXXX';
var aax_src = '302';
</script>
<script type="text/javascript" language="javascript" src="http://c.amazon-adsystem.com/aax2/assoc.js"></script>
</div>`;
}
I also tried to dynamically add the div inside my card,it shows inside the div but the banner doesn't appear.Below is the code showing how I did that.
ngAfterViewInit() {
let x: HTMLElement = document.getElementById('adv');
let s: HTMLScriptElement = document.createElement('script');
s.type = 'text/javascript';
// s.language = 'javascript';
let code = `var aax_size = '728x90';
var aax_pubname = 'XXXXXXX';
var aax_src = '302';`;
let src = document.createElement('script');
src.type = 'text/javascript';
// src.language = 'javascript';
src.src = 'http://c.amazon-adsystem.com/aax2/assoc.js';
try {
s.appendChild(document.createTextNode(code));
x.appendChild(s);
x.appendChild(src);
} catch (e) {
s.text = code;
document.body.appendChild(s);
}
console.log(x);
}
After scrapping every post in SO regarding or similar to this question I did not find any solution to this.I followed almost everything in those posts but nothing was working for me.After that I came across postscribe library which does the externally loading of any third party script.
First I installed the library and imported it in my component
import * as postscribe from 'postscribe';
After that all I did was calling a function inside my ngAfterViewInit function, by targetting the div with its id which in my case was adv and passed the script as a second parameter to this function.
ngAfterViewInit() {
postscribe('#adv', `<script type="text/javascript" language="javascript">
var aax_size='728x90';
var aax_pubname = 'XXXXXXXX';
var aax_src='302';
</script>
<script type="text/javascript" language="javascript" src="http://c.amazon-adsystem.com/aax2/assoc.js"></script>`);}
By doing this my banner was loaded.

Categories