I received an HTML file with 2 scripts in the head and I'm figuring out the best way to execute them in my react app. The first script load socket.io.js and the second contains the JS code for the upload system:
Original code
//...
<head>
<link rel="stylesheet" type="text/css" href="/css/upload.css" />
<script src="/js/socket.io.js"></script>
<script type="text/javascript" charset="utf-8">
var socket = io.connect("/", { path: "/app/socket.io" });
var SelectedFiles = [];
var SelectedFile = 0;
var paused = 0;
var FReader;
var dat;
window.addEventListener("load", Ready);
function Ready() {
//...
}
function handleUploads() {
//...
}
function StartUpload(Name, size) {
FReader.onload = function(evnt) {
socket.emit("Upload", {
//...
});
};
socket.emit("Start", {
//...
});
}
function getBlocks(data) {
//...
}
socket.on("MoreData", function(data) {
//...
});
function UpdateBar(percent) {
//...
}
socket.on("Done", function(data) {
//...
});
function Refresh() {
location.reload(true);
}
</script>
</head>
<body>
//...
First of all I moved the JS code content in a new JS file named "upload-script.js" and then used "React Helmet" module (https://www.npmjs.com/package/react-helmet) in order to load them in document head during component rendering:
My code
return (
<Row className="mb-4">
<Helmet>
<link rel="stylesheet" type="text/css" href="/css/upload.css" />
<script src="/js/socket.io.js" />
<script src="/upload-script.js" />
</Helmet>
<Colxx xxs="12">
Checking on browser the module correctly adds the scripts in the document head, but come out the following error:
./src/containers/form-validations/upload-script.js
Line 2:14: 'io' is not defined no-undef
Line 124:3: Unexpected use of 'location' no-restricted-globals
The browser cannot compile the app because in the JS file "upload-script.js" contains variables that are only defined in the first script.. how can I solve it? Is this a good way to add the scripts in a React app?
Any suggestions or guidance would be greatly appreciated. Thank you in advance.
Related
So I am developing an office add in which will essentially contain an iframe which will be running an application we own.
The problem is, I want to contantly record the url of the iframe so that i can save this to the addin state, aloowing us to use that information to load the iframe to the correct url each time the addin is reopened.
I cant figure out a way to output the url from within the iframe each time it changes? here is a sample of what i have, this doesnt contain the application just a couple of sample pages:
Home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title></title>
<script src="../Scripts/jquery-1.9.1.js" type="text/javascript"></script>
<script src="../Scripts/FabricUI/MessageBanner.js" type="text/javascript"></script>
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<link href="Home.css" rel="stylesheet" type="text/css" />
<script src="Home.js" type="text/javascript"></script>
<!-- For the Office UI Fabric, go to https://aka.ms/office-ui-fabric to learn more. -->
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.1.0/fabric.min.css">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.1.0/fabric.components.min.css">
</head>
<body>
</body>
</html>
Home.js
(function () {
"use strict";
// The initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
var iframew = document.createElement('iframe');
iframew.src = '../SecondPage/SecondPage.html';
iframew.id = 'iframe1';
iframew.onload = iframeLoaded(this.contentWindow.location.href);
document.body.appendChild(iframew);
});
};
// Helper function for displaying notifications
function iframeLoaded(location) {
console.log("log", location);
}
})();
Cant understand why people are downvoting this question, it was a genuine issue
Anyway, for anyone interested I solved this by attaching a a function after the iframe loads which outputs the url of the iframe at set interval periods
var iframew = document.createElement('iframe');
iframew.id = 'iframe1';
var baseUrl = '#YOUR BASE URL#';
let openUrl = getProperty('openurl');
if (!openUrl) {
console.log('No saved url');
iframew.src = baseUrl;
}
else {
console.log('saved url');
console.log(openUrl);
iframew.src = openUrl;
}
//when iframe loads attach function to save at interval
iframew.addEventListener('load', function () { setInterval(function () { iframeLoaded(iframew.contentWindow.location.hash, iframew.contentWindow.location.href); }, 4000); });
document.body.appendChild(iframew);
here is the iframeLoaded Function which also does some manipulation of the url and calles another function which saves the url to the doocument settings of the add-in:
function iframeLoaded(hash, location) {
//if not in an analysis dont save
if (hash.indexOf('#/dataset/') !== -1 ) {
console.log("Same url")
return
}
//remove # from hash
hash = hash.substr(1);
//concatenate base and hash
let newUrl = baseUrl + hash;
console.log(hash)
console.log(newUrl);
//save
if (Office.context.document.settings) {
saveProperty('openurl', newUrl);
}
}
I have problem when I try to load JSX file via native js function and script.onload event.
In my HTML file inside HEAD tag I have only one script to load:
<script src="js/01_jquery-1.12.2.min.js" defer></script>
Then in body I have this script which will load all other JS and JSX files
window.onload = function onLoad() {
function getScriptFile(inFile, scriptType, qname) {
....
}
function loadJsQ(inObj) {
....
}
// lib js
loadJsFiles({file: 'js/jquery-ui.min.js'});
loadJsFiles({file: 'js/bootstrap.js'});
loadJsFiles({file: 'js/babel-core-5-8-34-browser.js'});
loadJsFiles({file: 'js/react-with-addons.js'});
loadJsFiles({file: 'js/react-dom.js'});
//class app
loadJsFiles({file: 'classes/User.js'});
loadJsFiles({file: 'classes/MainApplication.js'});
//jsx
loadJsFiles({file: 'jsx/mainReact.jsx', type: "text/babel"});
//
$(document).dequeue('queueLoadJsFiles');
};
Function inside window.onload are:
function getScriptFile(inFile, scriptType, qname) {
var scriptType = scriptType || false;
var script = document.createElement('script');
if(scriptType){
script.type = scriptType;
}
document.head.appendChild(script);
script.onload = script.onreadystatechange = function( _, isAbort ) {
console.log("script",script);
if(isAbort || !script.readyState || /loaded|complete/.test(script.readyState) ) {
script.onload = script.onreadystatechange = null;
script = undefined;
if(!isAbort) {
console.log("Script is loaded", inFile);
setTimeout(function () {
$(document).dequeue(qname);
}, 100)
}
}
};
script.src = inFile;
}
Next function is:
function loadJsQ(inObj) {
var qname = "queueLoadJsFiles";
$(document).queue(qname, function() {
var inFile = inObj.file,
inType = inObj.type || false;
getScriptJQueryQueue(inFile, inType, qname);
});
}
Everything loaded and check via console, but jsx is not executed.
My MainReact.jsx file is
//file jsx/mainReact.jsx
"use strict";
console.log("is ok in JSX???");
const SomeComponent = React.createClass({
....
});
const MainApp = React.createClass({
....
});
{
ReactDOM.render(
<MainApp />,
document.getElementById('mainAppCont')
);
let app = new MainApp();
}
My class files are
//file classes/User.js
class User{
constructor(){...}
...
}
And
//file classes/MainApplication.js
class MainApplication{
constructor(){...}
...
}
Before ask My Question, I have to say, When I load all js and jsx files via HEAD, it works.
My question is, why I can not load in this way via getScriptFile. Everything load except jsx file? Can you help me to solve this problem. I need to load via getScriptFile.
After all, HEAD is looking like this:
<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="max-age=0">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
<meta http-equiv="pragma" content="no-cache">
<title>Title</title>
<!-- CSS LIBS -->
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/bootstrap-theme.css">
<link rel="stylesheet" href="css/font-awesome.css">
<link rel="stylesheet" href="css/flags.css">
<!-- JS LIBS -->
<script src="js/jquery-1.12.2.min.js" defer=""></script>
<!-- added via getScript -->
<script src="js/jquery-ui.min.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/babel-core-5-8-34-browser.js"></script>
<script src="js/react-with-addons.js"></script>
<script src="js/react-dom.js"></script>
<script src="classes/User.js"></script>
<script src="classes/MainApplication.js"></script>
<script type="text/babel" src="jsx/mainReact.jsx"></script>
</head>
Line of code in JSX file, at top console.log("is ok in JSX???"); will not be executed...
All files are in place, and there are no any error in console.
:(
Thank you in advance!
I am creating an O365 app and I have 2 .aspx files, when the user clicks on the O365 mail app, I want each of these pages to be loaded based on the subject of the mail.
Scenario 1: Mail subject contains '#'
result: load page1
Scenario 2: Mail subject does not contain '#'
result: load page2
I have tried having an intermediate .js file where I have written the logic,
but when I do window.location = "path_to_aspx_file",
only the html is loaded but the js files do not run.
My current implementation:
I have LandingLogic.js
(function () {
"use strict";
//The Office initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
var item = Office.cast.item.toItemRead(Office.context.mailbox.item);
var sub = item.subject;
if (sub.indexOf("some text") > -1) {
window.location = "http://localhost:51776/File1.aspx";
}
else {
window.location = "http://localhost:51776/File2.aspx";
}
});
};
})();
After a bit of fumbling around.
I am able to navigate to each of these files now, but I am not sure how to access the mail subject from File1.aspx and File2.aspx.
Did you initialize the Office context before you using Office JavaScript API to get the subject? To redirect the HTML page easily, we can include the JavaScript like below:
Home.js:
/// <reference path="../App.js" />
(function () {
"use strict";
// The Office initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
app.initialize();
RedirectHTMLPage();
});
};
function RedirectHTMLPage() {
var subject = Office.context.mailbox.item.subject;
if (subject.indexOf("#") != -1) {
window.location.href = "https://localhost:44300/page1.aspx";
} else {
window.location.href = "https://localhost:44300/page2.aspx";
}
}
})();
The HTML page for redirecting:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title></title>
<script src="../../Scripts/jquery-1.9.1.js" type="text/javascript"></script>
<link href="../../Content/Office.css" rel="stylesheet" type="text/css" />
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<!-- To enable offline debugging using a local reference to Office.js, use: -->
<!-- <script src="../../Scripts/Office/MicrosoftAjax.js" type="text/javascript"></script> -->
<!-- <script src="../../Scripts/Office/1/office.js" type="text/javascript"></script> -->
<link href="../App.css" rel="stylesheet" type="text/css" />
<script src="../App.js" type="text/javascript"></script>
<link href="Home.css" rel="stylesheet" type="text/css" />
<script src="Home.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
I have tried having an intermediate .js file where I have written the logic, but when I do window.load = "path_to_aspx_file", only the html is loaded but the js files do not run.
Would you mind sharing the detail you using the “window.load”?
Fei Xue answer is correct . if you want to get subject from file2.aspx , add office.js reference and access subject same as file1.aspx inside the Office.initialize event
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
I have these js files:
main.js:
requirejs(['app']);
app.js:
define(['messages'], function (messages) {
alert(messages.getHello());
});
messages.js:
define(['global'],function () {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
global.js:
define(function () {
var stateObj = {hello:"test!"};
return {
getObj: function () { return stateObj; }
};
});
and index.html as:
<!DOCTYPE html>
<html>
<head>
<!-- Include the RequireJS library. We supply the "data-main" attribute to let
RequireJS know which file it should load. This file (scripts/main.js) can
be seen as the entry point (main) of the application. -->
<script data-main="scripts/main" src="lib/require.js"></script>
</head>
<body>
<h1>Example 2: load module using explicit dependency syntax</h1>
</body>
</html>
However when I open index.html, I get the below error in console:
Uncaught ReferenceError: global is not defined messages.js
where I'm making mistake?
You just need to set global as an argument to messages.js' function. requirejs will pass it in for you.
messages.js:
define(['global'],function (global) {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
This has the neat side effect that it is impossible to reference a module without declaring it as a dependency.
How are objects passed between the plugin's javascript and the javascript of the view? I'm playing around with an example code from the "apache cordova 3 programming" book and i'm stuck...
In my plugin.xml I set the namespace to "mool"
<js-module src="plugin.js" name="moool">
<clobbers target="mool" />
</js-module>
plugin.js
var mol = {
calculateMOL : function() {
return 42;
}
};
var molll = {
calculateMOLLL : function() {
return 42222;
}
};
module.exports = molll;
module.exports = mol;
index.html
<!DOCTYPE html> <html>
<head>
<title>Meaning of Life Demo</title>
<meta http-equiv="Content-type" content="text/html;
charset=utf-8">
<meta name="viewport" content="user-scalable=no,
initial-scale=1, maximum-scale=1, minimum-scale=1,
width=device-width;" />
<script type="text/javascript" charset="utf-8"
src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
function onBodyLoad() {
document.addEventListener("deviceready", onDeviceReady,
false);
};
function onDeviceReady() {
//alert("onDeviceReady");
};
function doMOL() {
var res = mool.calculateMOL();
alert('Meaning of Life = ' + res);
};
function doMOLL() {
var res = mool.calculateMOLLL();
alert('Meaning of Life = ' + res);
};
</script>
</head>
<body onload="onBodyLoad()">
<h1>MoL Demo</h1>
<p>This is a Cordova application that uses my custom
Meaning of Life plugin. </p>
<button onclick="doMOL();">Button1</button>
<button onclick="doMOLL();">Button2</button>
</body>
</html>
But when I run it only the second button works ... can somebody give me an explanation to this?
I already tried exporting both objects at once like:
module.exports = molll, mol;
but it still won't work...
This is a late comment but might benefit someone else. What worked for me was something similar to the following:
Try rewriting the plugin.js functions as follows:
module.exports.calculateMOL = function() { return 42; };
module.exports.calculateMOLLL = function() { return 42222; };
Drop the two export statements at the end (i.e. module.export = mol; and = molll;)
This should allow the two methods to be accessed as shown in the index.html file above.
It seems as if per definition it only assignes one object!
"The clobbers element specifies the JavaScript object assigned to the loaded JavaScript object."
I notice that in an app I had built, the module.exports property is taking an array, like below. That would allow you to put both your items in there(?) (I am just showing one object of the array in this snippet.)
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
{
"file": "plugins/org.apache.cordova.dialogs/www/notification.js",
"id": "org.apache.cordova.dialogs.notification",
"merges": [
"navigator.notification"
]
}, etc