Calling external JavaScript function in full stack app - javascript

I have used JavaScript for a while, but am brand new to Node.js and full stack development, taking on a small project as a hobbyist. I have Heroku set up to host the app at https://midi-writer.herokuapp.com/ and am able to edit my files and update the app (using git commands) through my Mac terminal.
I am having trouble figuring out how to call a JavaScript function in an external file (in /src/js/midiWriter.js) from the index.html page. Using <script type="text/javascript" src="bundle.js"></script> doesn't work (I think that the file is 'bundled' when I push it to Heroku), and I have also tried <script type="text/javascript" src="../src/js/midiWriter.js"></script>
Here is the full code for index.html with the function call at the end of the script.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Heart Beats</title>
<style>
</style>
</head>
<body>
<script type="text/javascript" src="bundle.js"></script>
<link rel="stylesheet" type="text/css" href="style.css"></link>
<form id="jsonFile" name="jsonFile" enctype="multipart/form-data" method="post">
<fieldset>
<h2>EKG File</h2>
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
<hr>
Frequency: <div id="frequency"></div>
Metadata:<div id="metaData"></div>
<div id="midiDownload">A link will appear here after the file has been processed</div>
</fieldset>
</form>
<script type="text/javascript">
function loadFile() {
var input, file, fr;
if (typeof window.FileReader !== 'function') {
alert("The file API isn't supported on this browser yet.");
return;
}
input = document.getElementById('fileinput');
if (!input) {
alert("Um, couldn't find the fileinput element.");
}
else if (!input.files) {
alert("This browser doesn't seem to support the `files` property of file inputs.");
}
else if (!input.files[0]) {
alert("Please select a file before clicking 'Load'");
}
else {
file = input.files[0];
fr = new FileReader();
fr.onload = receivedText;
fr.readAsText(file);
}
function receivedText(e) {
let lines = e.target.result;
var newArr = JSON.parse(lines);
var metaDataString = '';
document.getElementById("frequency").innerHTML = newArr.frequency + " Hz";
for (i = 0; i < newArr.meta.dashboard_measurements.length; i++){
metaDataString += newArr.meta.dashboard_measurements[i].description + ": "
+ newArr.meta.dashboard_measurements[i].value
+ " " + newArr.meta.dashboard_measurements[i].unit + "<br>";
}
document.getElementById("metaData").innerHTML = metaDataString;
}
midiWriter();
}
</script>
</body>
</html>
Here's the midiWriter.js file:
function midiWriter(){
var MidiWriter = require('midi-writer-js');
var track = new MidiWriter.Track();
track.addEvent([
new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
new MidiWriter.NoteEvent({pitch: ['C4', 'C4', 'C4', 'C4', 'D4', 'D4', 'D4', 'D4'], duration: '8'}),
new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'})
], function(event, index) {
return {sequential: true};
}
);
var write = new MidiWriter.Writer(track);
console.log(write.dataUri());
var app = document.getElementById('midiDownload');
var downloadLink = `Download Link`;
app.innerHTML = downloadLink;
}
I get the Uncaught Reference Error "midiWriter is not defined" with this version.
Please excuse any lame errors! I am brand new to this :)

Simple solution would be like this:
In your html file:
<script src="../src/js/midiWriter.js"></script>
<script>
...
midiWriter();
</script>
What the first line does is set the source of the file you will use and the in the plain script tags, you can use any function or variable that has global scope and is declared in the file whose path you declared in the <script src=""> tag.

Just hired someone on Fiverr to take a look. The problem is that I need to define the external function globally using window.midiWriter = function (){...

Related

Upload files from Local Folder using Dynamic WebTwain Cab file

I am very new to Dynamic WebTwain therefore apologies in advance If I am asking something to basic.
I currently have scanning functionality available in my Dynamic WebTwain but I need to implement Uploading functionality as well. For that I need to use ActiveX Object and DynamicTwain Cab Files. I am reading the documentation of WebTwain but there they are not using ActiveX or Cab files.
Currently, I am using below method for uploading,
DWObject.LoadImageEx("",1);
However, I do not want to upload the images in designated image viewer of Dynamosoft. I want to upload images in a custom Image viewer. For that, I am assuming that I will need to get the object of selected image for it to load in the custom image viewer. How can I do that?
Looking for guidance.
The LoadImageEx method is used to load local images to the Dynamic Web TWAIN image viewer, not for uploading images. To load images to a custom viewer, you just need to use the input element and FileReader.
For example:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<input type="file" name="document" id="document" accept="image/*">
<div id='customviewer'></div>
<script>
var input = document.querySelector('input[type=file]');
input.onchange = function () {
var file = input.files[0];
var fileReader = new FileReader();
fileReader.onload = function (e) {
var dataURL = e.target.result, img = new Image();
img.src = dataURL;
$("#customviewer").append(img);
}
fileReader.readAsDataURL(file);
}
</script>
</body>
</html>
Using LoadImageEx:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://unpkg.com/dwt#17.1.1/dist/dynamsoft.webtwain.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<input class="button" type="button" value="Load Images" onclick="loadFile()" />
<div id='customviewer'></div>
<script type="text/javascript">
var element = document.createElement('div');
var dwtObj = null;
Dynamsoft.DWT.CreateDWTObjectEx({
WebTwainId: '1'
},
function (obj) {
dwtObj = obj;
dwtObj.Viewer.bind(element);
},
function (err) {
console.log(err);
}
);
function loadFile() {
if (dwtObj) {
dwtObj.LoadImageEx('', 5,
function () {
dwtObj.ConvertToBlob(
[dwtObj.CurrentImageIndexInBuffer],
Dynamsoft.DWT.EnumDWT_ImageType.IT_PNG,
function (result, indices, type) {
var urlCreator = window.URL || window.webkitURL;
var dataURL = urlCreator.createObjectURL(result);
var img = new Image();
img.src = dataURL;
$("#customviewer").append(img);
},
function (errorCode, errorString) {
}
);
},
function (errCode, error) {
}
);
}
}
</script>
</body>
</html>

Create one folder for all files uploaded with google apps script and web app form

I have a web app with GAS. This web app have three inputs (Input 1, input 2, Upload file input), two for metadata and one for upload files. The upload input is a multiple upload file input. When I submit the form, the code must generate a folder for all files that I upload and register the data in a google sheet. For example i upload the file 1 and the file 2 with name or entry of the input 1 for the folder's name. But, when I go to google drive, the code generate two folders with the same name, in other words, for example, two folders, the first with the file 1 with the folder's name "folder 1" and the second with the file 2 with the folder's name "folder 1". How I get to generate only one folder for all files? What is wrong with my code? Can you help me?
greetings!
Here's my code:
<html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
crossorigin="anonymous"
/>
<title>TITLE</title>
</head>
<body>
<div class="container">
<h4>Ingrese datos</h4>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="numsip"
type="text"
placeholder="Set Name for folder"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="rut"
type="number"
placeholder="Set idnumber"
/>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-6">
<input
class="form-control"
id="files"
type="file"
placeholder="Seleccione Archivos"
multiple
/>
</div>
</div>
<button id="contactar" class="btn btn-primary" onclick="enviardatos()">
Generar carpeta
</button>
</div>
<script
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
crossorigin="anonymous"
></script>
</body>
<script>
function enviardatos() {
var sip = document.getElementById("numsip");
var rut = document.getElementById("rut");
var array = { numsip: sip.value, rut: rut.value };
const f = document.getElementById("files");
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {
fileName: f.files[i].name,
mimeType: data[0].match(/:(\w.+);/)[1],
data: data[1],
};
google.script.run
.withSuccessHandler((id) => {
console.log(id);
})
.addNewRow(array, obj);
};
fr.readAsDataURL(file);
});
alert("Se ha generado carpeta");
}
</script>
</html>
</html>
Here is the serverside function for google apps script:
function addNewRow(array, obj) {
var timestamp = new Date();
var parentFolderId = 'URLPARENTFOLDER';
var parentFolder = DriveApp.getFolderById(parentFolderId);
var user = Session.getActiveUser().getEmail();
var foldercreated = parentFolder.createFolder('SIP ' + array.numsip + '/' + array.rut);
var idfolder = foldercreated.getId();
var url = 'URLSHEET';
var values = SpreadsheetApp.openByUrl(url);
var ss = values.getSheetByName('DATA');
ss.appendRow([array.numsip, array.rut, timestamp, user, idfolder]);
var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
return foldercreated.createFile(blob).getId();
}
*I omitted the "doGet" function...
I believe your goal as follows.
You want to put the uploaded files to the specific folder.
When the folder name of "SIP "+array.numsip+"/"+array.rut is existing in parentFolder, you don't want to create the folder with the same folder name. You want to put the files to the existing folder.
Modification points:
In this case, I would like to propose to modify both the function of addNewRow at Google Apps Script side and enviardatos() in Javascript side.
In your current script, the new folder is created every run by var foldercreated = parentFolder.createFolder("SIP "+array.numsip+"/"+array.rut). So this part is required to be modified.
It checks whether folder of the same folder name is existing.
And, your Google Apps Script side, I think that var parentFolder=DriveApp.getFolderById(parentFolderId); at the bottom of function is not used.
But, there is one more important point in your script. The script in [...f.files].forEach((file, i) => {,,,}) is run with the asynchronous process. By this, even when the script at Google Apps Script side is modified, the duplicate folder names are created. So it is required to also modify the script of Javascript side.
When above points are reflected to your script, it becomes as follows. Please modify the function of addNewRow as follows.
Modified script:
Google Apps Script side:
Please set URLPARENTFOLDER and URLSHEET.
function addNewRow(array,obj) {
var timestamp = new Date();
var parentFolderId = "URLPARENTFOLDER";
var parentFolder = DriveApp.getFolderById(parentFolderId);
var user = Session.getActiveUser().getEmail();
var folderName = "SIP "+array.numsip+"/"+array.rut;
var foldercreated = parentFolder.getFoldersByName(folderName);
foldercreated = foldercreated.hasNext() ? foldercreated.next() : parentFolder.createFolder(folderName);
var idfolder= foldercreated.getId()
var url = "URLSHEET";
var values = SpreadsheetApp.openByUrl(url);
var ss= values.getSheetByName("DATA");
ss.appendRow([array.numsip,array.rut,timestamp,user,idfolder]);
return obj.map(({fileName, mimeType, data}) => {
var blob = Utilities.newBlob(Utilities.base64Decode(data), mimeType, fileName);
return foldercreated.createFile(blob).getId();
});
}
Javascript side:
Please modify enviardatos() in Javascript side as follows.
From:
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
google.script.run.withSuccessHandler((id) => {console.log(id);}).addNewRow(array, obj);
}
fr.readAsDataURL(file);
});
To:
Promise.all([...f.files].map((file, i) => {
const fr = new FileReader();
return new Promise((r, rj) => {
fr.onload = (e) => {
const data = e.target.result.split(",");
r({fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]});
}
fr.onerror = (e) => rj(e);
fr.readAsDataURL(file);
});
}))
.then(obj => google.script.run.withSuccessHandler(console.log).addNewRow(array, obj))
.catch(err => console.log(err));
References:
getFoldersByName(name)
Promise.all()

How do you read a local file on your PC and update it constantly in javascript?

So, I've made a java program that runs through a list of IPs, pings them, and updates a file on the devices status. I want to know how to open the file into a webpage and update it, so a user can open the webpage and just see a list of data from the file, they don't have to select the file or refresh the page.
Is this feasible to do with javascript/html?
This is the code I'm working with so far:
<html>
<head>
<title>Import Data</title>
<script>
var openFile = function() {
var input = event.target;
var reader = new FileReader();
reader.onload = function() {
var text = reader.result;
var node = document.getElementById('output');
node.innerText = text;
console.log(reader.result.substring(0,200));
};
reader.readAsText(input.files[0]);
setTimeout(openFile(),1000);
};
</script>
</head>
<body>
<input type='file' accept='text/plain' onchange='openFile()'><br>
<div id='output'>
</body>
</html>
But I can't seem to hunt down where to hardcode the path to the file in. When I use this manual selection method, it'll update once, whether the file increases in elements or decreases.
EDIT:
I've narrowed it down to where the file needs to be uploaded:
<html>
<head>
<title></title>
<script>
function uploadFile() {
var reader = new FileReader();
reader.onload = function(event) {
var contents = event.target.result;
console.log("File contents: " + contents);
};
reader.onerror = function(event) {
console.error("File could not be read! Code: " + event.target.error.code);
};
var fileInputElement = document.getElementById("FileName");
reader.readAsText(fileInputElement.files[0]);
console.log(fileInputElement.files[0]);
}
</script>
</head>
<body>
<input type='file' accept='text/plain' value='RESULTS.txt' id='FileName' onchange='uploadFile()' style="display:none;">
</body>
</html>
If I try to type just a file path in a string, it complains it's not type 'blob'. When I do this, it requires the user to enter a file name, but obviously it can't be seen. How can I make that 'file' variable a static variable so it always opens a that file without prompting the user?
Doing some more research, it's security reasons as to why you can't access a file from the local computer.
So, in lieu of all that, I made some code that will constantly load the selected file so you can see whenever it changes:
<html>
<head>
<title>Import Data</title>
<script>
var input;
var openFile = function() {
var reader = new FileReader(event);
reader.onload = function() {
var text = reader.result;
var node = document.getElementById('output');
node.innerText = text;
console.log(reader.result.substring(0,200));
};
reader.readAsText(input.files[0]);
setTimeout(openFile,1000);
};
</script>
</head>
<body>
<input type='file' accept='text/plain' onchange='input = event.target; openFile(event);'><br>
<div id='output'>
</body>
</html>

HTML5 Reading File

I am trying to develop an application where it allows the user to choose a file and then read it and display the text on the screen.
My code can be found here: http://jsfiddle.net/5sy076n5/1/.
<html>
<head>
<title>FileReader Example</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
function testRead() {
var fileSelector = document.createElement('input');
fileSelector.setAttribute('type', 'file');
fileSelector.click();
}
</script>
</head>
<body>
<h1>Example</h1>
<p>Read <a onClick="testRead();">File</a></p>
</body>
</html>
You may notice that I don't have an input tag inside the body. This is because I want the user to click on the tag rather than the text.
My problem is what I am suppose to do after fileSector.click();? How can I get what file was chosen?
You have already created the input element on runtime and you have the reference of it fileSelector
You can simply use this variable to FileReader API
function testRead() {
var fileSelector = document.createElement('input');
fileSelector.setAttribute('type', 'file');
fileSelector.click();
fileSelector.addEventListener('change', function () {
var file = fileSelector.files[0];
var reader = new FileReader();
reader.onload = function (e) {
var text = reader.result;
console.log(text); // Select *.txt file and see console
}
reader.readAsText(file);
});
}
DEMO

Load external SWF with parameters in AS3

I have a swf file created by EasyPano tourweaver software. the outpout is a swf file with some .bin files to config the swf and other files such as .jpg, .js and so on.
The software create a html file to add the swf but i have to load the swf using flash and AS3. the HTML and JavaScript that the software create is :
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mahan</title>
</head>
<body leftMargin="0" topMargin="0" rightMargin="0" bottomMargin="0">
<script type="text/javascript" src="swfobject.js"></script>
<div id="flashcontent">
To view virtual tour properly, Flash Player 9.0.28 or later version is needed.
Please download the latest version of Flash Player and install it on your computer.
</div>
<script type="text/javascript">
// <![CDATA[
var so = new SWFObject("twviewer.swf", "sotester", "100%", "100%", "9.0.0", "#000000");
so.addParam("allowNetworking", "all");
so.addParam("allowScriptAccess", "always");
so.addParam("allowFullScreen", "true");
so.addParam("scale", "noscale");
//<!-%% Share Mode %%->
so.addVariable("lwImg", "resources/talarmahan_1_firstpage.jpg");
so.addVariable("lwBgColor", "255,255,255,255");
so.addVariable("lwBarBgColor", "255,232,232,232");
so.addVariable("lwBarColor", "255,153,102,153");
so.addVariable("lwBarBounds", "-156,172,304,8");
so.addVariable("lwlocation", "4");
so.addVariable("lwShowLoadingPercent", "false");
so.addVariable("lwTextColor", "255,0,0,204");
so.addVariable("iniFile", "config_TalarMahan.bin");
so.addVariable("progressType", "0");
so.addVariable("swfFile", "");
so.addVariable("href", location.href);
so.write("flashcontent");
// ]]>
</script>
</body>
</html>
Please Help me!
Thanks
The answer is URLVariables passed to the URLRequest feed into load method of Loader:)
example:
var loader:Loader = new Loader();
var flashvars:URLVariables = new URLVariables()
flashvars["lwImg"] = "resources/talarmahan_1_firstpage.jpg";
flashvars["lwBgColor"] = "255,255,255,255";
flashvars["lwBarBgColor"] = "255,232,232,232";
flashvars["lwBarColor"] = "255,153,102,153";
flashvars["lwBarBounds"] = "-156,172,304,8";
flashvars["lwlocation"] = "4";
flashvars["lwShowLoadingPercent"] = "false";
flashvars["lwTextColor"] = "255,0,0,204";
flashvars["iniFile"] = "config_TalarMahan.bin";
flashvars["progressType"] = "0";
flashvars["swfFile"] = "";
flashvars["href"] = this.loaderInfo.url;
var request:URLRequest = new URLRequest("twviewer.swf");
request.data = flashvars;
loader.load(request);
addChild(loader);
also with following helper method you can get main SWF parameters (from it's html wrapper) and pass it to the loaded SWF:
public function getFlashVars(li:LoaderInfo):URLVariables
{
var vars:URLVariables = new URLVariables();
try
{
var params:Object = li.parameters;
var key:String;
for(key in params)
{
vars[key] = String(params[key]);
}
}
catch(e:Error)
{
}
return vars;
}
then
var loader:Loader = new Loader();
var request:URLRequest = new URLRequest("twviewer.swf");
request.data = getFlashVars(this.loaderInfo);
loader.load(request);
addChild(loader);
For SecurityError: Error#2000 and here - there are many reasons behind this error

Categories

Resources