Scriptaculous load parameter in FF 2.0.x - javascript

Greetings all,
I am attempting to explicitly load the effects.js and builder.js Scriptaculous libraries on a page, using this code:
<script type="text/javascript" src="/javascripts/scriptaculous.js?load=builder,effects"></script>
This works like a charm in FF 3.0.x, IE7 and Opera 9.6.x. It does not work in Firefox 2.0.x, however. The libraries never become loaded. In order to get them to load in FF 2.0.x, I must explicitly reference them with two extra <script /> tags, i.e.:
<script type="text/javascript" src="/javascripts/scriptaculous.js?load=builder,effects"></script>
<script type="text/javascript" src="/javascripts/builder.js"></script>
<script type="text/javascript" src="/javascripts/effects.js"></script>
Does anyone happen to know what the discrepency between FF 2.0 and 3.0 is that causes this behavior? Is there a better solution to my problem?
Thanks for your help!

I've had too much coffee today, so I figure I will give this a go.
One possibility is the load function in scriptaculous.js does not correctly do the processing to include the libraries passed to it as parameters (scriptaculous.js?load=builder,effects).
Try putting in an alert to see if the load function in scriptaculous.js is being entered into, if it is, then the process probably doesn't do what it's supposed to on FF2:
load: function() {
alert('In the load function!');
...rest of code here...
If it isn't, then (maybe) firefox 2 does not want to execute load.
The last part of load seems to do the work for including other libs:
$A(document.getElementsByTagName("script")).findAll( function(s) {
return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
}).each( function(s) {
var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
var includes = s.src.match(/\?.*load=([a-z,]*)/);
(includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
function(include) { Scriptaculous.require(path+include+'.js') });
});
From the above code, I can see that the includes variable should parse out the library names, see if that's being assigned anything, replace it with something like:
var includes = s.src.match(/\?.*load=([a-z,]*)/);
alert(includes[0] + ' ' + includes[1]);
That should give you a better idea of what's going on. While this is an interesting little problem, I would definitely go with the solution you proposed:
<script type="text/javascript" src="/javascripts/scriptaculous.js"></script>
<script type="text/javascript" src="/javascripts/builder.js"></script>
<script type="text/javascript" src="/javascripts/effects.js"></script>

Related

JavaScript not being executed in a section under Razor

I've managed to get the following to execute properly, meaning that I've set the renering etc. correctly. I do get to see the alert window.
#{ Layout = "~/Views/Shared/_Default.cshtml"; }
<h1>Eye candies</h1>
#section Footie
{
<script type="text/javascript">
alert("Ola!");
</script>
}
However, when I change that to execute a different script, showing a cool globe with visitors, I see nothing, nada, ziltch! No error, no nothing. Just empty page.
When I paste the URL into a browser, I get a JS source code back, so I'm assuming that this part works. But I have no ideas left how to investigate it further.
#section Footie
{
<script src="#Url.Content("//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&m=0&s=180&c=ff0000&cr1=ffffff")"
async="async"
type="text/javascript"></script>
}
I've added a static HTML page and pasted in the script there. Works like a charm! So it's definitely related to script execution under a view in MVC (or possible Razor syntax).
Suggestions?
Take a look at the url you are passing to the Url.Content method
#Url.Content("//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&m=0&s=180
&c=ff0000&cr1=ffffff")
In the url, the & are already encoded to & Url.Content method is going to encode the & again and you will get the result as
"//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&amp;m=0&amp;s=180&amp;
c=ff0000&amp;cr1=ffffff"
Now you have &amp; :)
The solution is to either not use the Url.Content() method
<script type="text/javascript" src="//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&
m=0&s=180&c=ff0000&cr1=ffffff" async="async"></script>
or do not encode the url passing to Url.Content() method let the method take care of encoding it.
<script type="text/javascript" src="#Url.Content("//ra.revolvermaps.com/0/0/5.js
?i=0w5jyvctga6&m=0&s=180&c=ff0000&cr1=ffffff")" async="async"></script>

Plugging in a jQuery plugin

I'm trying to use the jquery tokeninput plugin, the demos work fine however when I try to implement it I'm hitting a brick wall. Chrome chucks this at me:
Uncaught TypeError: Object [object Object] has no method 'tokenInput'
Below is an excerpt from my <head>, chrome's resource browser shows both jQuery and jquery.tokeninput are loaded fine. No URL issues.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="/media/js/jquery.tokeninput.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#token").tokenInput("/members/api/members/tokeninput_members/?format=json");
});
</script>
And showing that tokeninput has loaded:
Right, bare-bones page worked fine. After digging a while longer I found this buried at the base of the page:
<script src="http://code.jquery.com/jquery.js"></script>
It seems having multiple versions of jQuery loaded is not a good thing to do.
I am not sure if you already solved it or not. But Try this it should work if your sequence of jquery library inclusion is right (which it seems right), also remove one of jquery.min.js, jquery.js.
Then try this
<script type="text/javascript">
// Any valid variable name is fine.
var j = jQuery.noConflict();
j(document).ready(function () {
j("#token").tokenInput("/members/api/members/tokeninput_members/?format=json");
});
</script>
Check this out to understand why you might need this.
http://api.jquery.com/jQuery.noConflict/

Uncaught ReferenceError $ is not defined

I'm very new to JavaScript (just started a few hours ago and trying to get a script working). I went through a few tutorials on W3 and the 'hello world' code works when I paste it directly into my HTML but I'm having a problem with a script (I've had problems with other scripts as well but I am not sure what I'm doing wrong).
I have this code that I want to test in my HTML, I copied the HTML in and it looks the same then I made a file in my static folder called edit.js and copied the JavaScript into it (exactly as shown). It didn't work no errors on the page but when I click it nothing happens. I tried to paste a W3 'hello world' code in and that worked but this script does not.
I tried to inspect the code in Chrome and that's where I see the above error (under the resources tab). I can open the js file using Chrome which makes me think the js file is accessible and pointing correctly but I'm not sure how to get it working. I'm using Jinja2 as my template engine to render the HTML and in my header I have:
<script language="JavaScript" type="text/javascript" src="static/edit.js"></script>
and in my main template (the one that gets rendered on all pages) I have:
<script language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
edit.js:
(even putting it within the script tag directly on the page I want to use it on doesn't work)
$('#editvalue').click(function(e){$('#storedvalue').hide();$('#altervalue').show();});
$('#savevalue').click(function(e){
var showNew = $('#changevalue').val();
$('#altervalue').hide();
$('#storedvalue').show();
$('#storedvalue span').text(showNew);
});​
HTML:
(it's embedded in a larger page)
<head>
<script language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript" src="static/edit.js"></script>
</head>
... my html code..
<div id="wrapper">
<div id="container">
<div id="storedvalue"><span>Hello</span> [edit]</div>
<div id="altervalue" style="display:none;"><input type="text" name="changevalue" id="changevalue" value="Hello"> [save]</div>
</div>
</div>
I have never been able to successfully run a JavaScript that wasn't on W3 yet. I get the same problem with other scripts even though I see people online saying they work fine for them. Do I need to do anything extra to make this work?
My two questions are:
What am I doing wrong?
Because Javascript seems to just not work when there's a problem, is there a way to get errors or information on what's actually wrong?
I read Uncaught ReferenceError: $ is not defined? and have been trying to figure this out for the last hour and can't see my problem.
First you need to place the jQuery script tag first.
Second, you need to do one of the following things:
Put your code within this function:
$(document).ready(function(){/*CODE HERE*/});
Or like this:
$(function(){
/*CODE HERE*/
});
The DOM needs to be ready before you can use it. Placing your code within anonymous functions that are executed on the ready event of the DOM is how you can do this.
Edit:
$(function(){
$('#editvalue').click(function(e){$('#storedvalue').hide();$('#altervalue').show();});
$('#savevalue').click(function(e){
var showNew = $('#changevalue').val();
$('#altervalue').hide();
$('#storedvalue').show();
$('#storedvalue span').text(showNew);
});​
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
Script tag for jQuery should come before your custom javascript.
Follow by edit.js
<script type="text/javascript" src="static/edit.js"></script>
Try removing the language attribute..sometimes work for me. It's obsolete now .. i think
You need to include jquery before you can use it.

using getScript to import plugin on page using multiple versions of jQuery

I am developing an app on a page that uses jQuery 1.2.6, but I would like to use jQuery 1.4.2 for my app. I really don't like to use multiple versions of jQuery like this but the copy on the page (1.2.6) is something I have no control over. I decided to isolate my code like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<script type="text/javascript" src="jquery-1.2.6.min.js>
<script type="text/javascript" src="pageStuff.js"></script>
</head>
<body>
Welcome to our page.
<div id="app">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="myStuff.js"></script>
</div>
</body></html>
The file myStuff.js has my own code that is supposed to use jQuery 1.4.2, and it looks like this:
(function($) { //wrap everything in function to add ability to use $ var with noConflict
var jQuery = $;
//my code
})(jQuery.noConflict(true));
This is an extremely simplified version, but I hope you get the idea of what I did. For a while, everything worked fine. However, I decided to use a jQuery plugin in a separate file. I tested it and it acted funny. After some experimentation, I found out that the plugin was using the old version of jQuery, when I wanted it to use the new version. Does anyone know how to import and run a js file from the context within the function wrapping the code in myStuff.js?
In case this matters to anyone, here is how I know the plugin is using the old version, and what I did to try to solve the problem: I made a file called test.js, consisting of this line:
alert($.fn.jquery);
I tried referencing the file in a script tag the way external Javascript is usually included, below myStuff.js, and it came up as 1.2.6, like I expected. I then got rid of that script tag and put this line in myStuff.js:
$.getScript("test.js");
and it still came back as 1.2.6. That wasn't a big surprise -- according to jQuery's documentation, scripts included that way are executed in the global context. I then tried doing this instead:
var testFn = $.proxy($.getScript, this);
testFn("test.js");
and it still came back as 1.2.6. After some tinkering, I found out that the "this" keyword referred to the window, which I assume means the global context. I am looking for something to put in place of "this" to refer to the context of the enclosing function, or some other way to make the code in the file run from the enclosing function. I noticed that if I copy and paste the code, it works fine, but it is a big plugin that is used in many places, and I would prefer not to clutter up my file with their code. I am out of ideas. Does anyone else know how to do this?
When you load jQuery, all it does is to create a root jQuery object and set window.jQuery and window.$ to point to it. So you can simply load the old jQuery, copy window.jQuery to window.jQuery126, load the new jQuery, copy window.jQuery to window.jQuery142, and then change window.jQuery and window.$ whenever you want a plugin to use the other version.
This is an ugly and unstable hack but it should work as long as
all code written for the non-default version is encapsulated with (function($){...})($) (proper jQuery plugins should do this, and you can easily ensure it for your own code)
scripts used with different jQuery versions don't mess with each other's stuff (such as one binding an event handler and the other trying to unbind it)
Another, simpler but less maintainable solution is to simply edit the plugin to look like (function($){...})(jQuery142) instead of (function($){...})(jQuery)
Versions
There is a script that specifically attempts to fix this problem: Versions . It's rather old, though.
It's just a neat helper for doing the switching of versions.
While I have not tested this script myself, you can do something like this based on the GitHub repository for the project:
<!-- Old jQuery and it's plugins -->
<script type="text/javascript" src="../jquery/jquery-1.2.6.js"></script>
<script type="text/javascript" src="test-plugin-for-old.js"></script>
<!-- Include the Versions helper -->
<script type="text/javascript" src="versions.js"></script>
<!-- Include a new jQuery -->
<script type="text/javascript" src="../jquery/jquery.js"></script>
<script type="text/javascript">
Versions.add('jquery', 'latest', jQuery.noConflict(true));
Versions.add('jquery', 'default', jQuery);
</script>
<!-- Load a plugin into the new jQuery -->
<script type="text/javascript">jQuery = Versions.use('jquery', 'latest');</script>
<!-- Do whatever you need with the new jQuery -->
<script type="text/javascript" src="test-plugin-for-new.js"></script>
<!-- Finish up and use the old jQuery back -->
<script type="text/javascript">jQuery = Versions.use('jquery', 'default');</script>
On-Demand JavaScript Loading (Lazy Loading)
With that out of the way, there are some ways to do on-demand JavaScript loading, but I don't think they will work well with loading of jQuery since jQuery modifies and requires the presence of the window object.
Also, you might want to read about script loading. There's more details about it in this StackOverflow question and the article pointed out.
RequireJS
In the list, RequireJS is not mentioned. It's rather new and you can do things like:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script type="text/javascript" src="pageStuff.js"></script>
</head>
<body>
Welcome to our page.
<div id="app">
<script type="text/javascript" src="require.js"></script>
<script type="text/javascript">
require({context: "1.4.2"},
["http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"],
function() {
console.log($.fn.jquery); // returns 1.4.2
// myStuff.js
});
require({context: "1.2.6"},
["http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"],
function() {
console.log($.fn.jquery); // returns 1.2.6
});
</script>
</div>
</body></html>
I always go for the newest stuff, haha, so I'm recommending this. However, due to the nature of loading the jquery (it modifies window as mentioned above), all references to $ and jQuery outside and beyond the last require in the HTML code block above, will refer to the jQuery 1.2.6.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" />
<script type="text/javascript">
$new = $.noConflict();
document.write("$new = " + $new.fn.jquery + "<br/>");
document.write("$ = " + $.fn.jquery + "<br/>");
</script>
I just tried this and it seems to work, $ reports to be the old version and you just have to make sure to use $new when invoking jquery for the stuff you want to do with 1.4.2
jQuery is actually a variable in the window context. So whenever you load a jQuery library it will create that variable in the window context if you load it outside any function.
I believe you could do something like this to achieve what you want. Although somewhat restrictive, theoretically it should work:
<script type="text/javascript">
// Get new jQuery code
$.get( "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js", function (data, textStatus, XMLHttpRequest){
if(data){
// data should contain the file content. eval() it
eval(data);
// Use jQuery 1.4.2 from here, only inside this callback function.
}
}, "html" );
</script>
This is ugly, but should do the trick.
For now, I am going along with Tgr's solution. Here are the details of how I implemented it:
page.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<script type="text/javascript" src="jquery-1.2.6.min.js>
<script type="text/javascript" src="pageStuff.js"></script>
</head>
<body>
Welcome to our page.
<div id="app">
Here is our app.
<script type="text/javascript">
var oldJQuery = $;
</script>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="myStuff.js"></script>
</div>
</body></html>
myStuff.js:
var jq142 = jQuery.noConflict(true);
(function($) {
var jQuery = $;
$(function() {
//init app stuff
includeScript("jCarousel.js", function() {
//init carousel stuff
});
});
})(jq142);
function includeScript(URL, callback) {
window.$ = window.jQuery = jq142;
window.$.ajax({
url: URL,
dataType: "script",
error: function() {
window.$ = window.jQuery = oldJQuery;
},
success: function() {
if (typeof callback != "undefined")
callback();
window.$ = window.jQuery = oldJQuery;
},
async: false
});
}
I still don't like the idea of putting another variable (jq142) into the global namespace, but I couldn't think of any reasonable way around it. If I come up with something better, I will post it here.

Cannot get Adobe AIR's ApplicationUpdaterUI() to work

Here is my problem - I'm trying to write a self-updating application, but I keep getting an error saying that runtime.air.update.ApplicationUpdaterUI() does not return a constructor.
Here's the relevant section of the code; there are other javascript files being included, but I don't think that any of them would be actively breaking AIR itself.
<html>
<head>
<script type="text/javascript" src="./js/AIRAliases.js"></script>
<script type="text/javascript" src="./js/jquery-1.3.1.js"></script>
<script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"></script>
<script>
$(document).ready( function() {
var appUpdater = new runtime.air.update.ApplicationUpdaterUI(); // line 64 in this example
}
</script>
</head>
<body> ... stuff ... </body>
</html>
And the error that I get when I test it is
TypeError: Value is not a constructor. Cannot be used with new.
at app:/index3.html : 64
at app:/js/jquery-1.3.1.js : 2912
at app:/js/jquery-1.3.1.js : 686
at app:/js/jquery-1.3.1.js : 2916
at app:/js/jquery-1.3.1.js : 2936
Verify the path in that script tag for the SWF, I'm guessing you do not have the reference to the ApplicationUpdater_UI.swf correct.
Air is basically complaining that it cannot find a runtime.air.update.ApplicationUpdaterUI() method to call anywhere, which likely means it can't find the SWF (or I suppose it's possible the SWF is corrupted).
Not sure if this is related, but neither $(document).ready nor .load will work if you load the .swf before the script. Make sure you put the .swf reference at the very bottom of your page.

Categories