How to share java script methods between html and svg? - html

I have got a html page embedded with a .svg. I have written most of the logic in java script and would like to share the same .js between html and .svg file:
for ex: I have got the following in mylogic.js:
var xmlDoc = null;
function loadXmlDoc() {
xmlDoc = new XmlDoc.....
}
function onHtmlLoad() {
loadXmlDoc();
}
function onSvgLoad() {
xmlDoc.getElemementById(...
}`
and in the Html, I have got
<html>
<script src="mylogic.js"></script>
<body onLoad='onHtmlLoad();">
...
<object id='svgid' data='sample.svg'.../>
...
</body>
</html>
and the java script included in the html page is not visible in the embedded .svg file so I have to include them again like...
<svg...onload="window.onSvgLoad();">
<script xlink:href="mylogic.js></script>
</svg>
since I included the .js file twice, I am getting the xmlDoc as null inside onSvgLoad() function. I believe, there should be a way to get the same instance of xmlDoc loaded from html in svg. but I am not getting it..?
alternatively I tried not to include .js file in svg instead tried changing onload to onload="window.top.onSvgLoad();" ; then to onload="window.parent.onSvgLoad();" but still did not work!
*Please note that I am using IE9 with its native support for Html5.

javascript included in the html page IS visible from the embedded .svg file. Remove the script tag from the embedded svg and call the methods you want as parent.method e.g. if mylogic.js had
function hello()
{
return "hello";
}
you could write
<script>
alert(parent.hello());
</script>
in the embedded .svg file to call it.

Related

How to get SVG document data to be inserted into the DOM?

I'm trying to load an SVG file from a CDN using this code:
<object type="image/svg+xml" data="https://cdn.mywebsite.com/path/file.svg"></object>
The SVG file is in an S3 bucket served by CloudFront CDN. It's content-type is set to "image/svg+xml". To the best of my knowledge, my S3 bucket and CDN are configured to allow CORS requests from any origin.
If I look at the browser Network tab, the HTTP GET request succeeds and it receives the SVG data in response. However, the document data is not inserted into the DOM, so it doesn't display and cannot be accessed by JavaScript.
How can I embed the SVG document into my webpage so that it becomes an accessible part of the DOM?
As Robert Longson kindly commented, embedding directly is impossible. But I did find a way.
I used this JavaScript (uses axios library):
var parser = new DOMParser();
let response = await axios.get('https://cdn.mywebsite.com/path/file.svg');
let svgDocument = parser.parseFromString(response.data, "image/svg+xml")
If CORS is configured correctly it allows the request, then you can parse the response body into a document. From there you can process the document or embed it.
Provided you are allowed to read the SVG, this native Web Component <load-svg>
reads the SVG as text
adds SVG to shadowDOM as DOM element
moves the style element from lightDOM to shadowDOM
So style is only applied to current SVG
<load-svg src="//graphviz.org/Gallery/directed/fsm.svg">
<style>
svg { height:180px }
text { stroke: green }
path { stroke: red ; stroke-width:3 }
</style>
</load-svg>
<script>
customElements.define('load-svg', class extends HTMLElement {
async connectedCallback() {
let src = this.getAttribute("src");
let svg = await (await fetch(src)).text();
this.attachShadow({ mode: 'open' }).innerHTML = svg;
this.shadowRoot.append(this.querySelector("style"));
}
});
</script>
More complex example: How to make an svg interactive to gather comments/annotations on depicted elements

Integrate ts into html: uncaught ReferenceError clickbutton not defined

I try to build a simple CRUD frontend with no frameworks! I try to integrate a TypeScript file (intex.ts) into my index.html but it keeps beeing not found so that the called functions are undefined. I'm aware that browsers can't handle typescript but need javascript. I build my app before testing and all ts files get compiled. I tried integrating the compiled js file but it's not found either. All my frontend code is in directory src/public.
How do I connect my public/index.html with my public/index.ts so that the fundtions work?
relevant index.html code
<head>
<script type="text/typescript" src="index.ts"></script>
</head>
<body>
<button onclick="clickButton()">Click</button>
</body>
all index.ts code
function clickButton() {
document.getElementById("cases").innerText = "Hello Cases"
}
error i'm getting when clicking the button
index.html:18 Uncaught ReferenceError: clickButton is not defined
at HTMLButtonElement.onclick (index.html:18)
I use express in the backend and use express.static:
app.use(express.static("src/public"));
It seems to be an error caused because the function is defined outside of the global scope.
You can try to assign the function to the global window object just below of the function declaration:
function clickButton(){
...
}
window.clickButton = clickButton; // Now the function can be accessed from global scope
Also u can try to add the eventlistener on your JS file instead of using the html attribute onclick:
function clickButton(){
...
}
document.querySelector('.button-smth').addEventListener('click', clickButton);
This way you don't need to assign the function to the global scope at all, but you will need to add the class '.button-smth' (or whatever) to the html button element.
Hope this helps!
Your ts need to be compiled to js first. Then, you could possibly use it as follows -
function clickButton() {
document.getElementById("cases").innerText = "Hello Cases"
}
<head>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
<button onclick="clickButton()">Click</button>
<div id="cases"></div>
</body>
Note: This is just a possible solution

My HTML + JavaScript code works on online editors, but not offline

I'm working with Sheets, for converting google sheets into JSON files, and then with their API transform the JSON into javascript objects.
The problem is that the code works just fine in online editors just like Tryit from W3Schools or Codepen, but if I put it in an HTML file and open it with Chrome or Edge, it won't work. Does anyone know why? Will it work if I mount the site online?
<head>
<!-- Add Sheetsu Web Client script to the head -->
<script src="//script.sheetsu.com/"></script>
</head>
<body>
<div id="list"></div>
<script>
// API returns array of objects
// Iterate over them and add each element as a list element
function successFunc(data) {
data.forEach(function(item, i) {
document.getElementById("list").innerHTML += "<li>" + item.Precio + " " + item.Tipo + "</li>";
});
}
function errorFunc(e) {
console.log(e);
}
Sheetsu.read("https://sheetsu.com/apis/v1.0su/110ccf6a6812", {}).then(successFunc, errorFunc);
</script>
</body>
Thanks in advance
The problem is this:
<script src="//script.sheetsu.com/"></script>
When you start a resource/asset URL with "//" and without a protocol (http|https), it matches the protocol of where the page is loading. If you are opening a local html file directly, that protocol becomes file://, so the requested URL ends up being file://script.sheetsu.com/, which of course does not exist.
Change it to:
<script src="https://script.sheetsu.com/"></script>
I have tried Firefox and it worked. Check the image below:

use an include to include an html file that contains a script

I am working on a Google Apps Script. My situation is that I have an index.html file and a few others which should all share a menu on the side.
I therefore have a function as follows
function include(File) {
return HtmlService.createHtmlOutputFromFile(File).getContent();
};
and use
<?!= include('leftMenu'); ?>
to include that in my html files.
The problem I have is that in the included file there is a function called that is defined in my Code.gs
<div class="leftmenu">
Main menu<br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=newInvoice'>New invoice</a><br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=index'>Home</a>
</div>
This function works as I would expect as long as these lines are in the "main" html file but they produce text if they are in the "included" html file.
I hope that makes sense and some one is kind enough to explain what the problem is and hopefully how I can get round it.
Thank you
Neill
14 Dec. 2016 edited to try and explain exactly what my problem is
I have a html file named “newinvoice.html”.
This has javascript functions in it as follows
<script type="text/javascript">
function formSubmit() {
google.script.run.withSuccessHandler(updateUrl).onSubmitButton(document.forms[0]);
}
function updateUrl(url) {
var successMsg = document.getElementById('output');
successMsg.innerHTML = 'New invoice created, saved and sent per Email';
}
</script>
I can move these functions into a separate html file as you suggested. This is called menu_JS.html and is included in my main file with
This works perfectly.
I have a call to one of these these functions - also in the main html “newinvoice.html” This is as follows
<div class="leftmenu">
Main menu<br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=newInvoice'>New invoice</a><br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=index'>Home</a>
</div>
If I move this into a separate file “leftMenu.html” and include that in “newinvoce.html” with
Then the output no longer works.
It appears that the scripts are trying to run before the files are included instead of the include and then the execution as I am used to from PHP.
As always, I appreciate anyone willing to take the time to help me. This is frustrating. Thank you!
Create another HTML file and put the script you want to run client side in that file. Then use the same include statement to include that file.
So make menu_JS.html and place your functions in that, between script tags:
<script>
firstFunction(){
alert("In the first function");
}
secondFunction(){
alert("In the second function");
}
</script>
And in your main HTML template file, preferable after the body loads, place:
<?!= include('menu_JS'); ?>
NOTE that the script is in an HTML file and NOT a Script file.
EDIT: Nov 15 2016
Below is the variation of the function which I have that is working for my needs. Note that I am evaluating the included html file. I had previously used code more similar to your (commented out) and changed it to this some time ago:
function include(filename) {
// return HtmlService.createHtmlOutputFromFile(filename)
return HtmlService.createTemplateFromFile(filename).evaluate()
.getContent();
}
//function includeRaw(filename) {
// return HtmlService.createTemplateFromFile(filename).getRawContent();
//}
And this is how I load the initial html file. This is often in the doGet() function, but may be elsewhere
var result=HtmlService.createTemplateFromFile('GridView').evaluate()
.setTitle('Boxwood Registrations')
.setWidth(1285)
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return result;

Loading HTML templates with RequireJS

I am trying to load HTML templates with RequireJS and I am trying to use a RequireJS plugin for that. https://github.com/ZeeAgency/requirejs-tpl . Here's the sample code provided in the plugin for loading a template.
define(['tpl!your-template-path.tpl'], function(tpl) {
return tpl({your: 'data'});
});
The problem with this function is that there is no way to pass the data to this function and get the rendered html. I'm new to javascript, so please help.
And do you know of a simpler way to load HTML templates with requirejs?
I use the text plugin, and underscore for the templating
You use it like this:
your_template.html
<p>hello <%=name%><p>
In your requirejs file,
define(['underscore', 'text!./your_template.html'], function(_, yourTemplate ) {
var compiledTemplate = _.template(yourTemplate );
return = compiledTemplate({name: 'moe'});
});