how to call a javascript function from another document - javascript

I know this is a very basic, very newb question, but i cant seem to make it work.
I have 2 different javascript documents, one named movies and the other named calculator.
I would like to call calculator.js function, and put it inside my code in movies.js so that it would display it's result inside.
My code in movies.js is like this:
function formatState (movies) {
if (!movies.id) { return movies.text; }
var $movies = $(
'<span><!--CALL JS. FUNCTION HERE--> ' + movies.text + '</span>'
);
return $movies;
};
my calculator.js
function calculate_price(value) {
//some data
}
at the end display result would be something like: 39.99€ star wars
Any help is appreciated!

This isn't as basic of a question as you might think, because JS doesn't really have a clear pattern for this.
Check out the answer to this question.

Javascript does not support the concept of "includes" or "imports". If you want to do something like this you either:
Reference both .js files in your HTML page - the order in which they are loaded is important.
Use another library to help you with dynamic loading a Javascript file before executing any code. Require.js is an alternative. jQuery has a way to allow you to do this, but you will introduce another dependency...
More details here: How do I include a JavaScript file in another JavaScript file?

Related

How do you use multple files in a JavaScript project that will not be used as a web application? Need a single working example

I'm kind of going nuts here.
I need to start writing a stand alone non web application in JavaScript.
My problem is that I can run (using nodejs) the script just fine, but I can't split the code that I need to write among multiple files because then I don't know how to include them.
Rigth now all I want is the simplest working example of including a JS file inside another so I can use the functions defined there (or class if I so choose).
My test.js looks like this.
const { outputText } = require("./text_module.node.js");
outputText();
While my text_module.node.js looks like this:
function outputText(){
console.log("hello world");
}
My package.json looks like this:
{
"type": "text_module.node.js"
}
I have tried
Adding export before the function. It tells me export is unexpected
Using this notation: import { something } from "a_path". Anything that uses this notation will get me an "Unexpected token {" error.
The current configuration simply tells me that outputText() is not a function. So I'm out of ideas.
I don't know how else to search. I've been searching for hours on this topic and it seem that no matter where I look there is some HTML code that is needed to tie everything togeter or using another third party tool. Using jQuery loads stuff "asynchronically" which is not what I need. I want it to sequential.
Is JS just NOT suppossed to be used like other scripting languages? Otherwise I can't figure out why this is so complicated. I feel like I'm missing something big here.
If you want to use const { outputText } = require("./text_module.node.js");,
export it as module.exports = { outputText: outputText }.
In your question,
Adding export before the function. It tells me export is unexpected
Because it's an es6 thing and nodejs doesn't support all es6 features. You can refer to this answer for more details on that.

How to place other JavaScript file links in a Javascript? [duplicate]

This question already has answers here:
How do I include a JavaScript file in another JavaScript file?
(70 answers)
Closed 6 years ago.
I have a bunch of JavaScript links at the bottom of one of my HTML template. I want to create a separate JavaScript file that will only contain all the source links in it.
So instead of cluttering my template footer I want all the links in one JavaScript file. How can I achieve that?
What I'm really asking is how I can get a similar effect as the CSS #import functionality for JavaScript.
And if that is not possible can I place a block of HTML at the footer of my template from a different HTML file?
You could do this with ajax but an easy way is to just append them with jquery
$('.div').append('<script src="myscript.js"></script>');
hope that helps
You can create a seperate js file and a object in it. This object can have multiple keys and their value will these links. Return this object from the file
Hope this snippet will be useful
linkFile.js
var AllLinks = function(){
var _links ={};
_links.keyOne ="link1";
_links.keyTwo ="link2";
return {
links:_links
}
}
Also include this file using script tag
In other file you can retrieve this value as
AllLinks.links.keyOne & so on
Have an array that holds the link to your script files and then you have two options either to use $.getScript() to load each one Or by building an HTML out of it and appending it to your head or body tag. I prefer head tag to keep all the scripts and css files.
Your array of script files
var JsFiles = ["script1.js","script2.js","script3.js","script4.js"];
First approach using $.getScript()
JsFiles.each(function(i,v){
$.getScript(JsFiles[i], function( data, textStatus, jqxhr){
console.log( textStatus ); // Success
});
});
Disadvantage of the above approach is that the getScript makes a async calls to your script files that means if the script2.js is dependent on the script1.js (for example if script1.js is some plugin file which use initialize in script2.js) Then you will face issues.
To overcome you might have to then use Promises or write a callback on each getScript success function which will trigger next script load and so on..
If the order of the script loading is not important then above approach is good to go.
Second approach by building HTML
var scriptTags ="";
JsFiles.each(function(i,v){
scriptTags += "<script src='"+ JsFiles[i] +"'></script>";
});
$('head').append(scriptTags);
Good thing about this approach is that the script files will now load synchronously and you will not face the dependency problem. But make sure the independent files start from first and the dependent files come at last.

Calling controller function from gsp

I need to call a controller function from javascript on my gsp.
I have read different solutions from hundreds of places but none worked.
The problem which I found closest to mine was this.
But I am not repeating the same mistake as this and thus the solution didn't help.
I have a tag like this which calls the javascript function
<g:select name="poNumber" noSelection="['':'Select PO Number']" from="${com.rerq.PurchaseOrder.list()}"
onchange="getProject(this.value)" />
And the javascript function looks like this
function getProject(poNumber){
var projectName = document.getElementById("projectName");
var newData = ${remoteFunction(controller: 'sow', action: 'getProject', params: ['poNumber':poNumber])};
}
And the function I need to call is
def getProject(String poNumber) {
String projectName = Sow.find("from Sow as s where s.poNumber=?", [poNumber])
return projectName
}
The controller function might have mistakes as I am completely new to groovy and grails. But my understanding is that the control isn't reaching here so this should not be the cause of any problem.
I am getting below exception
No signature of method: remoteFunction() is applicable for argument types: (java.util.LinkedHashMap) values: [[controller:sow, action:getProject, params:[poNumber:null]]]
I tried using remoteFunction() in g:select itself but it threw another exception which said
Attribute value quotes not closed ...
even though they were.
Any help is greatly appreciated.
To use remoteFunction with Grails 3 you need to add the ajax-tags plugin: org.grails.plugins:ajax-tags:1.0.0
Actually you can have your gsp recognize some Grails functions inside your js if the script is inside the gsp and anything you need for your js is created on the server side. In your case it seems you want to do an ajax call so you could have the following.
project.gsp (Consider that you already loaded jQuery)
<g:select name="poNumber" noSelection="['':'Select PO Number']" from="${com.impetus.rerq.PurchaseOrder.list()}"
onchange="getProject(this.value)" />
And in the same file you have
<script type="text/javascript">
function getProject(poNumber){
jQuery("#yourTarget").load("${createLink(action: 'getProject')}",{poNumber: poNUmber},function(response, status, xhr ){
if ( status == "error" ) {
alert("No data loaded.")
}
});
}
</script>
As you see a gstring in load("${}",... is used because it will be parsed in the server and at client side your actual js it will parse to load("yourcontrollerName/getProject",..... Why not code the url directly in the js? Because by using createLink() it is less likely to make reference mistakes.
EDIT
If you want to do this but using an external js file, you would need a way to pass the url, to the js, and use a simple load function. So something like this will be helpful
<g:select name="poNumber" noSelection="['':'Select PO Number']" from="${com.impetus.rerq.PurchaseOrder.list()}"
onchange="getProject(this.value, \'${createLink(action:'getProject')}\')" />
Once on the server onchange="getProject(this.value,\'${createLink(action:'getProject')}\')"would be parsed to onchange="getProject(this.value,'yourController/getProject')". Be wary that I might have messed up the ""s and ''s so verify your html output.
And you would need a js function that accepts the uri
function getProject(value, targetUri){
....
}
What you need to review is when is your function needed, on the server o in the client;if the functions are inside a gsp or not; And if not available, how could you pass data to them.
You cannot access grails's controller from javascript. I haven't tested it but this might work.
<g:createLink controller="sow" action="getProject", params="['poNumber':poNumber]"/>
Also, if you use Google Chrome's developer's tool, you will see how your javascript code is displayed. Make sure it is in right syntax.

jQuery: NewBie Questions, how to call function from another class in jquery?

I have function getCartItems in cart.js and I want to call that function in another class checkout.js than how can I do this ?
You need to include the script file cart.js in your page before you include checkout.js. Assuming the function getCartItems is declared in the global namespace, that's all you have to do.
However, don't confuse a Javascipt source file for a class. Javascript does not have classes in that sense.
I hate to throw a more complicated answer in here but one thing you can do to help simplify things is to use pseudo namespaces. Here is an example:
// In cart.js
var CartNS = {};
CartNS.getCartItems = function(){
function text here...
}
// In checkout.js
CartNS.getCartItems();
By organizing things into namespaces it can make it easier to deal with scope issues (one of the most difficult concepts in JavaScript) and it makes it a little easier to find things as well. This is also a way to simulate Classes in JavaScript. A decent example to get you started is: 3 ways to define a JavaScript class

Javascript functions

We are attempting to only make available certain functions to be run based on what request address is.
I was wondering how we could do this:
if(condition1)
{
$(document).ready(function() {
...
...
// condition1's function
});
}
else if(condition2)
{
$(document).ready(function() {
...
...
// condition2's function
});
else if...
I was wondering what a good pattern would work for this? since we have all of our functions in one file.
It depends on what your conditions are like...
If they're all of a similar format you could do something like
array = [
["page1", page1func],
["page2", page2func],
...
]
for(i=0; i<array.length; ++i)
{
item = array[i];
if(pageName == item[0]) $(document).ready(item[1]);
}
I like Nick's answer the best, but I might take a hash table approach, assuming the 'request address' is a known fixed value:
var request_addresses = {
'request_address_1': requestAddress1Func,
'request_address_2': requestAddress2Func
};
$(document).ready(request_addresses[the_request_address]);
Of course, request_addresses could look like this as well:
var request_addresses = {
'request_address_1': function () {
/* $(document).ready() tasks for request_address_1 */
},
'request_address_2': function () {
/* $(document).ready() tasks for request_address_2 */
}
};
I don't see any problem with that. But this might be better:
$(document).ready(function() {
if (condition1)
// condition1's function
else if (condition2)
// condition2's function
...
});
It would probably be cleaner to do the site URL checking on the server (if you can?) and include different .js files depending on the condition, e.g.
** Using ASP.NET MVC
<html>
<head>
<%
if(Request.Url.Host == "domain.com")
{ %><script type="text/javascript" src="/somejsfile1.js"></script><% }
else
{ %><script type="text/javascript" src="/somejsfile2.js"></script><% }
%>
</head>
</html>
This way, each js file would be stand-alone, and also your HTML wouldn't include lines of JS it doesn't need (i.e. code meant for "other" sites)
Maybe you could give more detail as to what exactly you are doing, but from what I can tell why wouldn't you just make a different JS file containing the necessary functions for each page instead of trying to dump all of them into one file.
I would just leave all of the functions in one file if that's the way they already are. That will save you time in rework, and save the user time with reduced latency costs and browser caching. Just don't let that file get too large. Debugging and modifying will become horrendous.
If you keep them all in one file, Add a script onn each page that calls the one(s) you want.
function funcForPage1() {...}
function funcForPage2() {...}
Then, on page1
$(funcForPage1);
etc.
Instead of doing what you're planning, consider grouping the functions in some logical manner and namespace the groups.
You'd have an object that holds objects that holds functions and call like this:
serial = myApp.common.getSerialNumber(year,month);
model = myApp.common.getModelNumber(year);
or
myApp.effects.blinkText(textId);
If you wanted to hide a function or functions per page, I suppose you could null them out by function or group after the load. But hopefully having things organized would satisfy your desire to clean up the global namespace.
I can't think of a particularly elegant way to achieve this using only JavaScript. If that's all that's available to you, then I'd at least recommend you use a switch statement or (preferably) a hash table implementation to reference your functions.
If I had to do something like this, given my development environment is fully under my control, I'd break up the JavaScript into individual files and then, having determined the request, I would use server side code to build a custom bundled JavaScript file and serve that. You can create cache copies of these files on the server and send client side caching headers too.
This article, which covers this technique as part of a series may be of interest to you.

Categories