I have a scripts.js file that includes a function inside that i want to access within an EJS templates.
in the templates i included a header, in the header I added a script rel to scripts.js
<script src="/scripts/scripts.js" type="text/javascript"></script>
I tested it though console.log("test") and when the template is being called I see "test" appears in the console.
when I try to call an actual function (verify_data) within the EJS template i get an error verify_data is not defined.
the error code within the EJS looks like this:
<p><em>Submited By <%= verify_data(results.user.username) %></em></p>
the function check if the argument passed is null/undefined, if yes the data returns if not "n/a" string returns instead.
How do i access JS functions directly within EJS template ?
Thanks,
Assuming you're not using a SPA framework, you need to add a tag which will be either replaced by the function or to contain the data you want to store.
Look at this code snippet
<p><em>Submited By <span id='userData'></span></em></p>
<script>
//This is the script.js
function verify_data(userName) {
return `My data with '${userName}'`;
}
</script>
<script>
let data = verify_data("EleFromStack"); // assuming <%=results.user.username%> = "EleFromStack"
document.querySelector("#userData").textContent = data;
</script>
This is my index.js file:
function fun()
{
var obj;
}
This is my index.html file:
<script>
src="js/index.js"
</script>
I want to use variable obj here.
I saw some solutions to create a variable and pass in index.html but is there any way of injection?
Actually, obj is a JSON object. I forgot to mention that previously. How would I use the JSON object keys and values in my index.html outside of the script tag?
Try out AngularJS. With this, you can declare variables in $scope and use it in your html like:
JavaScript:
...some angular logic...
$scope.foo = "bar";
...some other angular logic...
HTML:
<p>{{foo}}</p>
There are many tutorials out there. Read the documentation. It may be what you are looking for.
Although there isn't any way to inject a JS variable into HTML simply, you can use a javascript function to do the same thing:
In index.js:
function fun()
{
return obj; // Assuming obj is a defined variable.
}
document.getElementById("toReplace").innerHTML = fun();
In index.html
<p id="toReplace"></p>
<script src="index.js"></script>
Essentially, your javascript will replace the content of the <p> tag, which has the ID "toReplace", with the value of fun().
I'm just starting with Flask, so I may be overlooking something very obvious. I have loaded my javscript file with this:
<script src="{{ url_for('static', filename='Page.js') }}"></script>
then I try to instantiate an object from that js file:
<script>
var page = new Page("index");
</script>
In Page.js, I have this:
var Page = function(page) {
alert("init");
<some other things>
}
<and then some object methods Page.prototype.init_standard = function() {} etc>
The alert isn't alerting, though I am expecting it to. Also, if I put an alert before the instantiation in the HTML page, I get the alert, if I put an alert on the line after the instantiation on the HTML page, I don't get the alert. I'm not sure if this is a Flask issue or javascript -- I'm quite new at both.
EDIT: To nip this possibility in the bud, the javascript file is getting loaded according to the development server, status 304
Page.js needs to just define a function that creates the object you want. So Page() should just be a function that ends with 'return this;'. Correction returning this is not strictly required for object creation.
function Page(page) {
alert("init");
... Your code and methods...
// Example Method:
this.foo = function(param) {
... function body ...
};
return this;
}
And then you can create an object with:
var page_object = new Page("index");
page_object.foo(some_data);
I figured it out after looking at the browser debugger. It said Page was not defined. After some trial and error, I realized I can't use {{ flask templating notation inside the javascript file, probably because it isn't loaded as a template so no parsing of it in that way occurs. Anyway, I ended up just moving the {{ }} link to the html template and passing it in as an argument to the javascript.
I would like to update JavaScript files for every release. So, I need to add the version number to the JavaScript files which i am using and I would like to give the version number from the web.config file.
I had added a key in the web.config as:
<add key="VersionNumber" value="1"/>
I have an js file as:
<script src="~/Scripts/Utilities/DashBoard.js" type="text/javascript"></script>
I know we can give "version number" to the js file like:
<script src="~/Scripts/Utilities/DashBoard.js?version="**data**"" type="text/javascript"></script>
In asp.net mvc3 razor we can get the value from web.config in javascript as:
var VersionData = "#System.Configuration.ConfigurationManager.AppSettings["VersionNumber"].ToString()";
But i had an confusion how to place this "VersionData" in the "data" of the above script line.
And I had given this VersionData in the page load function. Is it correct?
When I change the version number for every release will it update .js file. Can any one please help me to find the solution?
Try using the WebConfigurationManager class from System.Web.Configuration namespace instead.
Example
string versionNumber = WebConfigurationManager.AppSettings["VersionNumber"].ToString()
In order to use the version parameter in your .js library, I'd recommend passing your arguments through an object.
In DashBoard.js
var MYSCRIPT = MYSCRIPT || (function(){
var _args = {};
return {
init : function(Args) {
_args = Args;
},
returnValue : function() {
alert(_args[0]);
}
};
}());
Your Razor Page
<script type="text/javascript" src="~/Scripts/Utilities/DashBoard.js"></script>
<script type="text/javascript">
MYSCRIPT.init(["versionNumber", #versionNumber]);
</script>
Accessing the value (either in your page or JS)
MYSCRIPT.returnValue();
I would recommend creating your own Html helper to obtain the active script name from your web.config.
I am writing a simple counter, and I would like to make installation of this counter very simple for users. One of the simplest counter code (for users who install it) I ever see was Google Analytics Code
So I would like to store main code in a file and user who will install my counter will need just to set websiteID like this:
<html><head><title></title></head><body>
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var websiteId = 'XXXXX';
</script>
</body></html>
Here is my code:
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var page = _gat.init('new');
</script>
and this is my JS file:
(function() {
var z = '_gat';
var aa = function init(data) { alert(data); alert(z);};
function na() {
return new z.aa();
}
na();
})();
I tried to understand Google Analytics javascript code but I failed to do this. Can anyone suggest how can I specify variable between tags and then read it in anonymous function which is located in a javascript file ?
Thanks.
In your example, websiteId is a global variable. So it is accessible everywhere including anonymous functions unless there is a local variable with the same name
<script> var websiteId = "something"; </script>
Later in the page or included js file...
(function() {
alert(websiteId); //this should work
})();
Can anyone suggest how can I specify variable between tags and then read it [...]
Not if your tag has both a SRC attribute and JS content.
<script type="text/javascript" src="http:/x.com/x.js"></script>
.. is different from,
<script type="text/javascript">
var x = 1;
</script>
One framework that optionally adds JS variables to SCRIPT tags is Dojo. So if you're using Dojo you can add variables to the global djConfig hash by writing,
<script type="text/javascript" src="mxclientsystem/dojo/dojo.js"
djConfig="
usePlainJson: true,
parseOnLoad: true
">
</script>
Dojo does this by running through the SCRIPT tags and evaluating the custom djConfig attribute.
This does not, however solve your problem.
You do really want two SCRIPT tags. One saying,
<script type="text/javascript">
var websiteId = '123456';
</script>
which will set a global variable websiteId and a second one,
<script type="text/javascript" src="http:/x.com/myreporter.js"></script>
which can load from anywhere and read out the websiteId variable and, I assume, report it back.
You can pass variables to an anonymous function like so:
(function(arg1, arg2, arg3) {
alert(arg1);
alert(arg2);
alert(arg3);
})("let's", "go", "redsox");
// will alert "let's", then "go", then "redsox" :)
I'm not entirely clear about what you're asking, but...
You can tag any HTML element with an id attribute, then use
document.getEntityById() to retrieve that specific element.
You can also give any HTML element user-defined attributes having names of your own choosing, then get and set them for that element within Javascript.
I think you've got a bit confused with how JS objects are called.
z is a String, '_gat'. You can't call aa() on it because a String has no member called aa. aa is a standalone function stored in a local variable. Even if you did call aa(), it doesn't return anything, so using the new operator on its results is meaningless. new can only be called on constructor-functions.
I guess you mean something like:
var _gat= function() {
// Private variable
//
var data= null;
// Object to put in window._gat
//
return {
// Set the private variable
//
init: function(d) {
data= d;
}
};
}();
Then calling _gat.init('foo') as in your second example would set the variable to website ID 'foo'. This works because the _gat object is the return {init: function() {...}} object defined inside the anonymous function, keeping a reference (a ‘closure’) on the hidden data variable.
If you specify a src attribute as part of a script element, any code within the script element tags themselves will not be executed. However, you can add this functionality with the following code. I got this technique from Crockford (I believe it was him), where he uses it in of his talks on the unrelated topic of rendering performance and asynchronously loading scripts into a page to that end.
JavaScript:
(function() {
// Using inner class example from bobince's answer
var _gat = (function() {
var data= null;
return {
init: function(d) {
console.info("Configuration data: ", d);
data = d;
}
}
})();
// Method 1: Extract configuration by ID (SEE FOOT NOTE)
var config = document.getElementById("my-counter-apps-unique-and-long-to-avoid-collision-id").innerHTML;
// Method 2: search all script tags for the script with the expected name
var scripts = document.getElementsByTagName("script");
for ( var i=0, l=scripts.length; i<l; ++i ) {
if ( scripts[i].src = "some-script.js" ) {
config = scripts[i].innerHTML;
break;
}
}
_gat.init( eval("(" +config+ ")") );
})();
HTML:
<script type="text/javascript" src="some-script.js" id="my-counter-apps-unique-and-long-to-avoid-collision-id">
{some: "foo", config: "bar", settings: 123}
</script>
Both methods have their draw backs:
Using a unique and non-colliding ID will make determining the proper script element more precise and faster; however, this is not valid HTML4/XHTML markup. In HTML5, you can define arbitrary attributes, so it wont be an issue at that time
This method is valid HTML markup; however, the simple comparison that I have shown can be easily broken if your url is subject to change (e.g.: http vs https) and a more robust comparison method may be in order
A note on eval
Both methods make use of eval. The typical mantra concerning this feature is that "eval is evil." However, that goes with say that using eval without knowing the dangers of eval is evil.
In this case, AFAIK, the data contained within the script tags is not subject to inject attack since the eval'ing script (the code shown) is executed as soon as that element is reached when parsing the HTML into the DOM. Scripts that may have been defined previously are unable to access the data contained within the counter's script tags as that node does not exist in the DOM tree at the point when they are executed.
It may be the case that a well timed setTimeout executed from a previously included script may be able to run at the time between the counter's script's inclusion and the time of the eval; however, this may or may not be the case, and if possible, may not be so consistently depending on CPU load, etc.
Moral of the story, if you're worried about it, include a non-eval'ing JSON parser and use that instead.