Why is jQuery document ready closing off access to global variable? - javascript

I have a project where I have three separate JavaScript files (example1.js, example2.js and example3.js lets call them) scripted into one html file (index.html). These three JS files between them are responsible for an API call and manipulating the result.
One of the JS files, example1.js refers to a global variable located in example2.js and as they were both loading into the same html document I thought the access to said variable wouldn't be an issue and it did indeed work perfectly fine until I added the files to my RoR app. Due to Rails I had to encase the JS/jQuery code inside of $document.ready(function(){}
(I should probably should do this as a matter of course anyway?).
The effect this has had is that I am now getting a 'variable not defined' error on the global variable referred to by example1.js that is located in example2.js, even though other code in the same file is working correctly.
I went back to my original JS files away from RoR incase it was a Rails issue. However, encasing the code in my original files with the jQuery document.ready function has the same effect outside of the Rails environment. Can someone explain why this is and a possible solution?

I completely overlooked the fact that document.ready is itself a function and therefore removed everything from the global scope into the function scope of document.ready.

Related

Netbeans autocomplete not working on new projects

I've been working in Netbeans for about 6 months now, everything was working fine.... this morning however, I started a new project and for some reason there is no way to make cross-file autocomplete work.
I defined some global variables in one .JS file, some functions as well.
In another .JS file I try to reference the global or to call a functions, auto complete does not work. Heck I write the function down completely and properly and when I ctrl + click it, it will not take me to the declaration.
Both files are in the same project, both are linked to my Index.html.
I tried deleting the cache, didn't work.
I opened older projects (ones I worked on last week) and both the global variables and the functions that are written cross-files are visible....
Any clue what to do?
EDIT: Apparently there is issues with file names. If the name of the file is "config", "config2", "aaaaaconfig" the Navigator does not recognize anything in it as declared content... if I name the exact same file "blabla" it starts working... rename it to "config" again and it stops again...
Okay so after dangling with this for a long time, I've figured it out.... apparently the .js file must NOT have "config" in it's name. Putting it as answer so that others might find it. It is possible that this issue comes with any language, which is why most PHP coders have issues.... BDConfig is a pretty standard name for a PHP file for DB connections.

How to read model attribute from js outside jsp

If my javascript/jquery code is written inside a jsp-file, I can refer to Spring's modelAttribute value with "${varName}".
However I would like to move the javascript code into it's own file to keep the jsp-file more readable. When I do that, it won't however be able to find that modelAttribute anymore. How should I solve this problem?
How can I point to model attribute from a .js -file?
Thanks in advance!
Alright, I've experimented on my end to try to find and answer for this question.
Actually, it seems there's no direct solution, and here's why:
When you are moving your Javascript code to a separate file, this means that the browser will launch a separate request to fetch that file. As such, data that you store in your request scope (a.k.a. ${varName}) is not part of the request that fetches the .js file; it's only part of the request that fetches your .jsp file instead. As such, the ${varName} value will not be available in your Javascript file.
Another reason on top of the above: .js files are not processed as server-side code by the web engine (most likely Tomcat in this case), so the ${varName} text is outright ignored. For fun, I tried to do a hack: I renamed my script file from .js to .jsp, and used this within my .jsp page:
<script type="text/javascript" src="js/actually_javascript.jsp"></script>
It fooled the web server to process the file server-side, but this still didn't work, because of reason #1 stated above. It could work if you stored the value in the session instead, but at the end of the day, it would be kind of an ugly hack and you'd lose out on the code highlighting and completion features of your IDE, which would be fooled into thinking you're editing an actual .jsp file. Not recommended.
To conclude, I think the only way to access {$varName} inside your JavaScript is either:
Having the Javascript being a part of your .jsp file, within <script> tags
Having your Javascript in its own .js file, but still having a <script> tag in your .jsp page which initializes the module you programmed in the .js file and passes the values from the request, like ${varName}
You should initialize your javascript file via your jsp file.
Example:
Create a seperate script section for initialization of your variables after loading the .js file in your jsp page:
<script src="js-path/file.js"></script>
<script>
init(${varFromModel1}, ...);
</script>
And define the init-method in your javascript file:
function init(param1, ...) {
// initialize variables of .js file here
}
Remember, for this to work, you need to ensure, that the model-attribute output has correct javascript syntax.

using requirejs within a firefox xul extension

I would like to use requirejs to manage my code within a firefox xul plugin, and I can't get it to find my modules.
I know that xul doesn't play nice with the data-main attribute, so I have my main.js script as a second script:
<script src="chrome://myPackage/content/require.js" type="application/x-javascript"></script>
<script src="chrome://myPackage/content/main.js" type="application/x-javascript"></script>
This successfully calls the script, and the require function is available within main.js, but when I run
require(['lib1'], function(lib1){
alert(lib1.val1);
})
the alert never gets popped (lib1 is in the same directory as main.js).
I have tried this within and without setting the baseUrl as
require.config({
baseUrl: "chrome://myPackage/content/"
})
and it does not work either way.
Does anyone know how I can get require.js to look in the right place for my modules?
Addendum **
I added an error handling function and the error code returned is
http://requirejs.org/docs/errors.html#timeout
I have loaded the test module into a normal web page successfully. This seems to confirm that the issue is path configuration (it also takes the 15 second timeout before failing)
Firebug seems to have a working requirejs version. But more importantly, they have a far better mini-require.js that will not pollute the shared global scope when used in overlays (if used correctly :p)
https://github.com/firebug/firebug/blob/master/extension/modules/require.js
https://github.com/firebug/firebug/blob/master/extension/modules/mini-require.js
I suggest you have a look at these implementations and also the code using it.
Proactive warning:
Please note, that if your add-on uses code that defines lots of new properties on the scope in overlays (window) either by defining global functions or variables or implicitly declaring variables within functions, then this may interfere with other code running in the same scope (the browser code itself and other add-ons). Besides, should you want to submit your add-on to addons.mozilla.org, then a reviewer might not give it public status if your add-on "pollutes" the global scope/namespace in the main overlay.

Yabble - accessing functions loaded by yabble

Am having a problem with Yabble that I have not been able to solve.
From within my main html I load all of my js using yabble
<script>
require.setModuleRoot('./javascript/');
require.run('main')
</script>
I have a bunch of js (gamejs related). In one file I have function changeSimulationSettings(). Later within the same page I want to take user input and access the gamejs objects and change their state. The problem I am having is that I am unable to call changeSimulationSettings. It is not defined within the current context. Yabble does so much magic I am unable to find where it is defined or how to access.
<div>
<button type="button" onclick="updateSettings()">Update-Settings</button>
</div>
<script type="text/javascript">
function updateSettings(){
// access function defined in a js loaded by yabble
i.e. changeSimulationSettings()
}
</script>
All of the js is definitely being loaded as I have got functions calling each other from different files which does work. However, I am unable to call anything from js embedded within the entry web page.
Any help would be appreciated as I have been stuck on this one for hours and hours.
Thanks,
Code defined in modules is isolated and not available globally.
I would do it the other way around: from within a module attach an event handler. Do not use "onclick=" but instead in a module, where you have changeSimuSettings available, do something like this (e.g. using jquery or plain DOM):
$('button').click(changeSimulationSettings)
This is cleaner and you are not leaking globals. If you insist on doing it your way, you could export changeSimulationSettings to global and use the code you already have. Like so (I would not recommend that):
window.changeSimulationSettings = function() {...

jQuery getScript function with frames

I'm a novice at Javascript/Jquery programming, so an apology if this is a simple/silly question.
I am trying to use the jQuery .getScript() function to refresh part of an existing webpage. This webpage must be run on a local file system, and a large amount of the formatting is done using frames.
Right now, there’s three main frames- a sidebar which displays possible “scopes” to choose from, a main frame which displays the majority of the contents of the webpage, and a footer frame. The main entry into the page is in an index.html file, which loads a sidebar.html, main.html, and footer.html file into each of the respective frames.
In turn, the main.html has a number of javascript files which it loads, the main being a main.js, which contains numerous functions to format/process the contents for this main window. After loading this javascript file, main.html loads a few javascript files, which contain the data which is going to be displayed in the main frame. These files that are loaded have a fixed data structure, and are dependent on the functions that were loaded by the main.js file.
Loading the webpage works fine now, but when a user tries to switch to another “scope”, the whole webpage is reloaded to make the switch. The only difference in the webpage is the content in the main.js frame, loaded in by a different set of .js files.
Enough text, let’s look at some code.
When the webpage loads, I tried to add a simple call to the getScript function in a .js file at the index.html level which handles switching scopes. This file, newFile, has different data definitions than the previously loaded oldFile.js which was loaded in the main.html file.
$.getScript(/js/newFile.js);
However this doesn’t work, since newFile.js depends on a parseData() function which is in main.js.
If I open firebug up, parseData is not located in the dom tab, which I assume is related to some scoping issue with the main.html and main.js file existing in a different frame.
I tried to do some targeting to the correct “frame” but I don’t think I understand jQuery enough to know what is happening.
$(window.parent.frames[0]).getScript(/js/newFile.js);
Any suggestions?
If I were to type into firebug console “parseData” it can not find it: “ReferenceError: parseData is not defined”
However, if I type in window.parent.frames[1].parseData, it can find the function.
Sorry about all the rambling and poor understanding of javascript. Hopefully someone can provide some assistance!
Thanks
.getScript() executes the loaded script in the global context. I would assume that since your parseData() function is not available at global scope. You could try defining parseData globally by wrapping it in a jQuery.globalEval() call like so:
$.globalEval("
function parseData(){
alert('It works!');
}
");
I haven't tested but I have run into similar situations using the javascript setTimeout() function since it also executes globally.

Categories

Resources