Accessing Functions From Other JS Files - DOJO - javascript

Im trying to call a function from another js file that is located in the same application directory as my main js script and html file. I receive an error claiming that the referenced function does not exist. I have referenced both of the scripts in the main html file in the proper order but cant for the life of me figure out why it cannot detect the function. I can only assume it has something to do with how dojo parses through the files and have experimented with both its dojo/domReady! and dojo/ready modules in hopes to force scripts to load. I feel like this should be much simpler than Im making it out to be. Any help would be greatly appreciated.
html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Asset View</title>
<meta charset="utf-8">
<link rel="stylesheet" href="http://js.arcgis.com/3.14/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">
<link rel="stylesheet" href= "styles/styles.css">
<script src="http://js.arcgis.com/3.14/"></script>
<script src="scripts/requests-js.js"></script>
<script src="scripts/layout-js.js"></script>
<script src="scripts/xmain-js.js"></script>
</head>
<body class = "claro">
</body>
</html>
requests-js.js
require(["dojo/dom","dojo/on","dojo/request","dojo/json","dojo/parser","dojo/ready"
], function(dom,on,request,JSON,parser,ready) {
ready(function() {
console.log("request start");
function sendRequest (url,assetCode,fromDate,toDate) {
console.log("Request innit");
request(url,{
method: "POST",
handleAs: "json",
headers: {"Content-Type": "application/json"},
data: JSON.stringify(
[
{
"AssetCodes": assetCode,
"FromGasDay": fromDate,
"ToGasDate": toDate
}
]
)
}).then(function(resp){
console.log(JSON.stringify(resp));
var naStorageJSON = resp;
});
}
console.log("request end");
});
});
main-js.js
require([
"dojo/dom","dojo/on","dojo/parser","dojo/json","dojo/request","dojo/ready"
], function(dom,on,parser,JSON,request,ready) {
ready(function() {
console.log("Main Start");
var url = "http://*********";
var assetCode = ["**"];
var toDate = "****";
var fromDate ="*****";
on(dom.byId("senecaLakeBtn"),"click", sendRequest(url,assetCode,toDate,fromDate));
console.log("Main End");
});
});

The issue is scope here. By declaring an empty array at the top of the js script (outside of its successive functions) the function can be accessible to other scripts in the application.
var app = [];
require(["dojo/dom","dojo/on","dojo/request","dojo/json","dojo/parser","dojo/ready"
], function(dom,on,request,JSON,parser,ready) {
ready(function(){
app.sendRequest = function sendRequest (url,assetCode,fromDate,toDate) {
...
...
}
}
it can them be called upon from other scripts by referencing
app.sendRequest(arg1,arg2,arg3);

Related

Can't call function from body onload (uncaught reference error: resetLoginForm is not defined) javascript

I have a body onload calling a function in javascript. I Have tried many things, but the console just prints to the error log:
uncaught reference error: resetLoginForm is not defined
My code is as follows:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<title>Login Page</title>
<script src="/client/js/popper.min.js"></script>
<script src="/client/js/js.cookie.min.js"></script>
<script src="/client/js/querystring.js"></script>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" media="screen,projection"/>
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script type="module" src="js/login.js"></script>
</head>
<body class="blue-grey darken-2" onload="resetLoginForm()">
<script src="js/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
This is the JavaScript code that I am trying to use:
import * as Cookies from "/client/js/js.cookie.min.js";
function resetLoginForm() {
if (Cookies.get("destination") === undefined) {
window.location.href = "/client/index.html";
}
const loginForm = $('#loginForm');
loginForm.submit(event => {
event.preventDefault();
$.ajax({
url: '/admin/login',
type: 'POST',
data: loginForm.serialize(),
success: response => {
if (response.startsWith('Error:')) {
alert(response);
} else {
Cookies.set("sessionToken", response);
window.location.href = Cookies.get("destination");
}
}
});
});
You're using new ECMAScript modules (<script type="module" ...>), which are isolated to their own scope. Your function resetLoginForm() isn't being defined in the global scope (Where you can essentially call it from your onload body function). You need to define it explicitly in your module:
import * as Cookies from "/client/js/js.cookie.min.js";
window.resetLoginForm = {
if (Cookies.get("destination") === undefined) {
window.location.href = "/client/index.html";
}
...
Ideally though, you should not be using onload at all. Just add an event listener in:
import * as Cookies from "/client/js/js.cookie.min.js";
function resetLoginForm() {
if (Cookies.get("destination") === undefined) {
window.location.href = "/client/index.html";
}
...
}
// Attach an event, and call resetLoginForm when the document is done loading.
document.addEventListener("DOMContentLoaded", resetLoginForm);
Change is <script type="text/javascript" src="js/login.js"></script>
Cnages is please check once resetLoginForm function in onload.

Unable to push data to handlebars?

I used to use mustache.js for my templates on a quickbase app, but recently decided to switch over to trying handlebars so that I could use the if/then of it for a more appealing template.
However I can not seem to get them to work like mustache did, the Get for my module.js shows in the console, but after that the page doesn't load like it's supposed to (it usually loads the template.html)
module.js
var dbidApplication = "dbidHere";
var dbidTable = "dbidtHere";
var apptoken = "apptokenhere";
$.ajaxSetup({
data: {
apptoken: apptoken
}
});
var promise1 = $.get(dbidApplication, {
a: "dbpage",
pagename: "template.html"
});
var promise2 = $.get(dbidTable, {
act: "API_GenResultsTable",
query: "{3.EX." + kRid + "}",
jsa: 1,
options: "num-1",
});
$.when(promise1, promise2).then(function(html, data) {
//do some stuff with all the data
var template = Handlebars.compile(html[0]);
console.log(html[0]);
console.log(data[0]);
console.log(qdb_data);
$(template(qdb_data)).appendTo("#external");
});
My template has the source for handlebars and the div with id external
template.html
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.3/handlebars.runtime.min.js" type="text/javascript"></script>
<title></title>
</head>
<body>
<div id="external"></div>
</body>
</html>
I think you forgot to set qdb_data:
$.when(promise1, promise2).then(function(html, data) {
//do some stuff with all the data
var template = Handlebars.compile(html[0]);
var qdb_data = data[0];
console.log(html[0]);
console.log(data[0]);
console.log(qdb_data);
$(template(qdb_data)).appendTo("#external");
});

unable to call function in dojo module from another dojo module

I'm getting an Object doesn't support property or method error when I try to call a function in a dojo module. I have a main page and two modules. I call the first module from the main page and it works, I call the second module from the first and it works, but I get the error when I try to call the first module from the second. Here is my code:
main page:
<!DOCTYPE html>
<html >
<head>
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<script>
var dojoConfig = {
parseOnLoad:true,
async: true,
isDebug:true,
packages: [
{name: "Scripts", location: location.pathname.replace(/\/[^/]+$/, "") + "/Scripts"},
]
};
</script>
<script> src="http://js.arcgis.com/3.10/"></script>
<script>
require(["Scripts/Mod1", "Scripts/Mod2"],
function (Mod1, Mod2) {
Mod1.M1Method("call from main page");//works great
});
</script>
</head>
<body class="claro">
<div>look here you</div>
</body>
</html>
Module 1:
define(["Scripts/Mod2"],
function (Mod2) {
return {
M1Method: function (msg) {
alert(msg);
Mod2.M2Method("call from Mod1");//works great
},
M1Method2: function (msg) {
alert(msg);
}
}
});
Module 2:
define(["Scripts/Mod1"],
function (Mod1) {
return {
M2Method: function (msg) {
alert(msg);
Mod1.M1Method2("call from Mod2"); //JavaScript runtime error: Object doesn't support property or method 'M1Method2'
}
}
});
How can I make that call from Mod 2 to Mod1?
Thanks
You are trying to do a cyclic dependency. In module 2, use a require statement. Try something like this:
define(["require"],
function (require) {
return {
M2Method: function (msg) {
alert(msg);
try {
require(["Scripts/Mod1"], function(Mod1) {
Mod1.M1Method2("call from Mod2");
});
} catch (dohObj) {
alert('Doh!, this failed. Stupid answer: ' + dohObj.message);
}
}
}
}
);
Your html code has a typo in that you enclosed the 'script' tag too soon when including dojo.js. Should be something like
<script type="text/javascript" src="http://js.arcgis.com/3.10/"></script>
You need to fix that file first to properly include dojo and 'require()'.

Issue injecting external script with executeScript method in Cordova

I'm writing a dummy app to test how works the executeScript() method inside Cordova's InAppBrowser plugin. In particular, I'm trying to inject a javascript code inside one webview.
Here there is my index.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script type="text/javascript" src="phonegap.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<title>InAppBrowser Injection Test</title>
</head>
<body>
<div class="app">
<h1>Testing Injection</h1>
<div id="deviceready" class="blink">
<p class="event listening">Starting Mother WebView</p>
<div class="event received">
<p>Device is Ready</p>
</div>
</div>
</div>
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>
And the index.js file
var app = {
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
app.receivedEvent('deviceready');
var ref = window.open('http://www.example.net', '_blank', 'location=yes ,toolbar=yes, EnableViewPortScale=yes');
ref.addEventListener('loadstart', function(event) { alert('start: ' + event.url); });
ref.addEventListener('loadstop', function() {
//ref.executeScript({ code: "alert('Injected Code')" });
ref.executeScript({ file: "externaljavascriptfile.js" });
showalert();
});
ref.addEventListener('loaderror', function(event) { alert('error: ' + event.message); });
ref.addEventListener('exit', function(event) { alert(event.type); });
},
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
and last the externaljavascriptfile.js
alert('External Injected Code');
If I try to inject javascript code directly (i.e. uncommenting the line "ref.executeScript({ code: "alert('Injected Code')" });" ) all works fine and the alert is triggered after the page load, but if I try to inject an external javascript (i.e. using the line "ref.executeScript({ file: "externaljavascriptfile.js" });", nothing happens.
Am I missing something?
Actually, I think you already know the answer.
executeScript() method run in the child WebView.
ref.executeScript({ file: "externaljavascriptfile.js" });
In your code, executeScript() method is referenced http://www.example.net/externaljavascriptfile.js, not in your script file in /www/js cordova directory. Because executeScript() method injects JavaScript in childview as you know.
You can test the code with below. I've put the file in my website.
//...
onDeviceReady: function() {
var ref = window.open('http://www.haruair.com/', '_blank', 'location=yes, toolbar=yes, EnableViewPortScale=yes');
ref.addEventListener('loadstop', function() {
ref.executeScript({ file: "externaljavascriptfile.js" });
});
},
//...
FYI, if you need to get the data from childview, you can use callback.
//...
var ref = window.open('http://www.haruair.com/', '_blank', 'location=yes, toolbar=yes, EnableViewPortScale=yes');
ref.addEventListener( "loadstop", function() {
ref.executeScript(
{ file:'http://haruair.com/externaljavascriptfile.js' },
function() {
ref.executeScript(
{ code:'getSomething()' },
function(values){
var data = values[0];
alert(data.name);
});
}
);
});
//...
In externaljavascriptfile.js:
var getSomething = function(){
// do something and get the result from childview webpage
return { name : 'foo', age : 12 };
};
Use Ajax to get JS file data then inject it using execute script
$.ajax({
type: "GET",
url: cordova.file.applicationDirectory + "www/js/externalScript.js",
dataType: "text",
success: function (jsCode) {
ref.executeScript({code: jsCode}, function () {
console.log("Code Inserted Succesfully");
});
},
error: function () {
console.log("Ajax Error");
}
});
//ref is reference of inappbrowser
//i.e. var ref = window.open();
//url is url of your local javascript file
With this method you can add a script file which is located in the local APP's sandbox, and not around in the Internet.
Note, you need to cordova-plugin-file:
cordova plugin add cordova-plugin-file
Did you install the inappbrowser plugin?
I have this working in android as follows:
EDIT: Updated for cordova 7
Create the phonegap project
> cordova create JsExec
> cd JsExec
> cordova platform add android
> cordova plugin add cordova-plugin-inappbrowser
Update index.js -here is my onDeviceReady function:
onDeviceReady: function() {
this.receivedEvent('deviceready');
var w = window.open('http://www.example.net','_blank','location=yes');
w.addEventListener('loadstop', function(event) {
w.executeScript({file: "https://s3.amazonaws.com/avvi00/externaljavascriptfile.js"});
});
},
Deploy to my HTC
> cordova run --device
external script file is here
the full working copy of this project is here
regards,
Av
externaljavscriptfile.js is not linked in your html file.
You need to include it with the
<script type="text/javascript" src="path/externaljavascriptfile.js"></script>
tag or to load it dynamically with:
var script = document.createElement('script');
script.async = "async";
script.src = "path/externaljavascriptfile.js";
document.getElementsByTagName("head")[0].appendChild( script );
NOTE: you may need to put your code in a function to execute it.
Hope it works.

Simple way of displaying images from parse.com database using javascript

I was working on a very simple page which just pulls and displays images from a table in parse.com. I do not have much experience with javascript which might be evident from the code below.
I need the images to show up in a chronological order. With the current code, it works fine most of the times but is a little buggy.
There are 2 main problems:
1) Sometimes, randomly, one particular new image might not come on the top and instead show up somewhere in between.
2) This page works on Firefox and Chrome but NOT on IE.
Is there a better way to implement this or is there something that I should change? Any help would be appreciated.
Page source-
<!doctype html>
<head>
<meta charset="utf-8">
<title>My parse images</title>
<meta name="description" content="My Parse App">
<meta name="viewport" content="width=device-width">
<!-- <link rel="stylesheet" href="css/reset.css"> -->
<link rel="stylesheet" href="css/styles.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.2.0.min.js"></script>
</head>
<body>
<div id="main">
<script type="text/javascript">
Parse.initialize("xxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxx");
var config = {
parseAppId: 'xxxxxxxxxxxxxxxxxxx',
parseRestKey: 'xxxxxxxxxxxxxxxxxx',
streamName: 'parse-demo'
};
var getPhotos = function() {
var userImages = Parse.Object.extend("userImages");
var query = new Parse.Query(userImages);
query.find({
success: function(results) {
$('#photo-container').children().remove();
for(var i=results.length - 1; i>=0; i--){
var img = new Image();
img.src = results[i].get("image").url;
img.className = "photo";
document.body.appendChild( img );
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
};
function refresh (timeoutPeriod){
refresh = setTimeout(function(){window.location.reload(true);},timeoutPeriod);
}
$(document).ready(function() {
getPhotos();
// refresh(10000);
});
</script>
</body>
</html>
Internet Explorer blocks mixed content. Since Parse's JavaScript SDK requires SSL, you need to host your app using HTTPS as well in order to access it from IE.
Hey you made one mistake. it was not working for me. Then i found that it is url() not url.
The amendment is img.src = results[i].get("image").url();
<!doctype html>
<head>
<meta charset="utf-8">
<title>My parse images</title>
<meta name="description" content="My Parse App">
<meta name="viewport" content="width=device-width">
<!-- <link rel="stylesheet" href="css/reset.css"> -->
<link rel="stylesheet" href="css/styles.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.2.0.min.js">
</script>
</head>
<body>
<div id="main">
<script type="text/javascript">
Parse.initialize("xxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxx");
var config = {
parseAppId: 'xxxxxxxxxxxxxxxxxxx',
parseRestKey: 'xxxxxxxxxxxxxxxxxx',
streamName: 'parse-demo'
};
var getPhotos = function() {
var userImages = Parse.Object.extend("userImages");
var query = new Parse.Query(userImages);
query.find({
success: function(results) {
$('#photo-container').children().remove();
for(var i=results.length - 1; i>=0; i--){
var img = new Image();
img.src = results[i].get("image").url();
img.className = "photo";
document.body.appendChild( img );
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
};
function refresh (timeoutPeriod){
refresh = setTimeout(function(){window.location.reload(true);},timeoutPeriod);
}
$(document).ready(function() {
getPhotos();
// refresh(10000);
});

Categories

Resources