Showing posts with label error. Show all posts

ReferenceError: $ is not defined

This post will explain the root cause of the Reference Error in your browser’s console log. Also, list most common cases with examples and solutions. Without any further ado, lets see what a reference error is.

This is a common JavaScript error that says: you are trying to access a variable or call a function that has not been defined yet.

Reproducing the error:

// VARIABLES
foo; // ReferenceError: foo is not defined
var foo;
foo; // No more errors

// FUNCTIONS
bar(); // ReferenceError: bar is not defined
bar = function(){};
bar() // No errors

By now, you might have guessed the reason behind the "ReferenceError: $ is not defined" error. It is exactly the same as the bar() example above, but the name of the function is $ instead of bar this time. So, what it means is that we are trying to access the method $ that has not been defined yet. When is it possible? Only when jquery.js file has not been loaded successfully before we tried to call $().

Some common cases when error may occur

  1. Problem: Path to your jquery.js file is broken and it can not be found (Error 404).

    <script src="/wrong/path-to/jquery.min.js"></script>

    Solution: fix your path to jquery.js file. If your project is a public website, you better use Google hosted jQuery file.

    <script src="/correct/path-to/jquery.min.js"></script>
  2. Problem: jQuery plugin is included before jQuery file.

    <script src="/path-to/jquery.plugin.js"></script>
    <script src="/path-to/jquery.min.js"></script>

    Solution: Include jquery.js file before any jQuery plugin files.

    <script src="/path-to/jquery.min.js"></script>
    <script src="/path-to/jquery.plugin.js"></script>
  3. Problem: You are including jQuery file without the protocol in the URL and accessing the page from your local file system.

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

    Solution: Temporarily add HTTP protocol (http:// instead of //) in the URL while you are developing.

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
  4. Problem: jQuery file is included from the web, but you don't have an internet connection. It is a silly mistake, but you would be surprised how ofter it happens.

    <script src="http://www.example.com/js/jquery.min.js"></script>

    Solution: Include local jquery.js file copy or connect to the internet :)

    <script src="/js/jquery.min.js"></script>

If the above cases do not solve your case, try to figure out why jQuery is not loaded before the line where this error is thrown.

8+ methods that will not work in jQuery 1.9

There have been many method additions and deprecations in the last jQuery releases, but never so many changes that remove previous deprecations and make backward incompatible changes in a single release. Final release of jQuery 1.9 will be announced today. This article will help you get an overview of what’s changing and how to get prepared. So lets review these changes.

1) $.browser is no longer available

$.browser added in v1.0, deprecated since v1.3 and now it's gone. If possible use browser feature detection ($.support) instead of browser sniffing ($.browser). The documentation says that it may be moved to a plugin, but it's not yet (well, not considering jQuery Migrate of course). If you haven't used $.support before, we will cover it in our next post.

For those who really need just the browser sniffing feature back, you can copy-paste the highlighted code from jQuery 1.8.3's core here.

2) .andSelf() is renamed to .addBack()

.andSelf() added in v1.2, deprecated in v1.8. It's used for adding previous selection set to the current set in the chain.

For example: $('.first-set').children().andSelf() - would return a set with all children of the .first-set, plus .first-set's themselves. It took no arguments and now it has been replaced by .addBack() method that does the exact same thing, but accepts optional selector argument to filter out the set. So with the example above you could say: $('.first-set').children().addBack('div') - return all children of .first-set, plus .first-set's that are <div>s.

3) Removed deprecated .sub()

.sub() added in v1.5, deprecated in v1.7. Lets you create a copy of jQuery object, so that methods' default behaviours could be overwritten.

For example you could overwrite jQuery's .data() methods so that it would try to fetch required data from your server if it's not found on the element.

(function() {
  var copy = jQuery.sub();

  copy.data = function(element, key, value) {
    // Make sure user is trying to get, not set data
    if(!!value) return jQuery.data.apply(this, arguments);

    // Get data using default jQuery.data() method
    var data = jQuery.data.apply(this, arguments);

    if(!data) {
      // if no data, get it from the server
      data = $.ajax({ AJAX_INFO });
    }

    // Once we have the data, cache it using
    // original $.data() and return to the callee
    return jQuery.data.apply(this, arguments, data);
  };

  copy(document).ready(function($) {
    alert($(".test-elem").data();
  });

})();

If you want to study how it was accomplished, here is the related code from 1.8.3 code base.

4) Can't toggle through click events, only visibility

.toggle() added in v1.0, deprecated in v1.8. There were 2 .toggle() methods: one that animates show/hide, the other toggles click events. The one that toggles through click handlers is removed. So .toggle(function(){}, function(){}) will not work. Here is the related code in jQuery Migrate plugin.

5) No more $('img').error()

.error() added in v1.0, deprecated in v1.8. Not to be confused with $.error() method, that throws new Error(msg);

6) .attr() for working with attributes only

.attr('value', newValue) used to set property instead of attribute. To set current value use .prop('value', newValue) and .val(newValue) for form elements.

Learn the difference between property and attribute.

7) Removed "hover" pseudo-event

"hover" – there is no more event called hover. Instead use "mouseenter mouseleave". Please note, that only pseudo-event name is no longer available. You can still use .hover() method.

8) Global AJAX events triggered on document

ajaxStart, ajaxSend, ajaxSuccess, ajaxError, ajaxComplete, ajaxStop now must be bound to 'document'.

9) Internal undocumented changes

There are also some other internal methods that were either changed or removed (like .data('events') and $.clean()), but since they are not documented I guess you are not using them.

How to deal with all the changes?

As you can see jQuery 1.9 throws away many deprecated methods, but the team understands that there is a lot of code in production that relies on these features. So jQuery team provided us with jQuery Migrate plugin that makes code written prior to 1.9 work with it.

If you use unminified version of the plugin, it will log warning messages in console if your code uses any of the deprecated methods. The minified file is for production and it does not throw any warnings.

NS_ERROR_NOT_AVAILABLE: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMWindow.alert]

This is a common error in Firefox. It is logged in console when you try to call on non existent DOM API method. Seeing this error message is very common with methods call to alert(), confirm(), drawImage() (canvas) and window.open(). You may think "how those methods could be 'non-existent'?", since they are standard APIs of the window object. Well, that's true, they can't, but consider the case when browser blocks your alert or pop-up windows. Firefox pop-up blocker will make those methods not available in that context and should silently carry on with the next statement, but instead it throws an error.

To solve this problem:

  • make sure you are calling methods on non-null objects;
  • remove alert(), confirm() or open() methods in unload event handler. FF pop-up blocker ignores all window.open() methods in the unload handler.

The flavours of the error message:

  • NS_ERROR_NOT_AVAILABLE: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMWindow.alert]
  • NS_ERROR_NOT_AVAILABLE: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMWindow.confirm]
  • NS_ERROR_NOT_AVAILABLE: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage]

At the time of writing the problem has not been fixed.

Can't set / change CSS background image with jQuery problem solution

Hello everyone. I’ve been busy lately with some projects and could not write much on “jQuery HowTo” blog. So, when I came across this little problem, I thought I would share it with you.

Anyway, I was working on one of my projects and I needed to set a background image using jQuery on some div. At first my background setting code looked like this:

$('#myDiv').css('background-image', 'my_image.jpg');
// OR
$('#myDiv').css('background', 'path/to/image.jpg');

But to my surprise it didn’t do the trick. My div’s had no background images. FireBug showed no CSS background properties set and I could not see why background images were not being set by jQuery. Anyway, after 10-20 minutes I realized that jQuery sets CSS properties as key : value and in our case valued had to be in url(image.jpg) form.

Solution to “background images are not being set” problem is to set them like this:

$('#myDiv').css('background-image', 'url(my_image.jpg)');
// OR
$('#myDiv').css('background', 'url(path/to/image.jpg)');

diggthis.js + jQuery .wrap() is not working, causing Firefox to freeze and Safari to crush

I came across a forum post where user was experiencing problems while using Digg this (diggthis.js) button code with jQuery’s .wrap() method. According to him Mozilla Firefox (FF) is freezing and Apple Safari is crushing when he tries to wrap the div that contains diggthis.js file with another new div like so:

<div class="rounded"> 
  <script type="text/javascript"> 
    digg_url = "myURL.com"; 
  </script> 
  <script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script>
</div>

And the jQuery code is:

$(document).ready(function(){ 
    $("div.rounded").wrap('<div></div>'); 
});

This code seems to crush those browsers. Another way to do this is to remove the div that contains the script (.rounded), then create a new <div> and then insert the removed div (.rounded) back into the newly created div like this:

$(document).ready(function(){ 
    $("div.rounded").remove().wrap('<div></div>').appendTo("#somewhere"); 
});

How to make jQuery / Prototype / MooTools & others play nicely with Smarty

Smarty is the first template engine I have learned and used in my projects. Smarty makes your PHP code cleaner and promotes the V in MVC. Here is an example of Smarty template:

<html>
<head>
<title>User</title>
</head>
<body>
    User Information:<br />
    Name: {$name}
</body>
</html>

Smarty will replace the {$name} with the variable that you set in your PHP code. Anyway, do you see the problem that might arise when you try to embed your jQuery code or any other javascript library (like Prototype, MooTools, Extjs, etc.) that uses $ as a function name in the <head>?

Smarty parses the file and whenever it encounters the {$ it would try to parse it and replace with the PHP variable like in this example here:

<html>
<head>
<title>User</title>
<script type="text/javascript">
    $(document).ready(function(){
        $(".clazz").css("color", "red");
    });
</script>
</head>
<body>
    User Information:<br />
    Name: {$name}
</body>
</html>

The problem:

Smarty would not care that { and $ are on different lines and would see it like {$(".clazz.... The code above would cause this Smarty error:

Fatal error: Smarty error: [in templateFile.tpl line 5]: syntax error: unrecognized tag: $(".clazz").css("color", "red"); (Smarty_Compiler.class.php, line 455) in C:\PHP\smarty\libs\Smarty.class.php on line 1092

The solution:

There are couple of things you can do about this problem:

  1. Move your javascript (jQuery, Prototype, etc.) code into the external .js file.
  2. Use jQuery() instead of $().
  3. Use Smarty’s {literal}...{/literal} directives to tell Smarty parsing engine that it should not interpret the code within the block.

Example:

Here is how we can rewrite our javascript code above using the 3rd tip:

<html>
<head>
<title>User</title>
<script type="text/javascript">
{literal}
    $(document).ready(function(){
        $(".clazz").css("color", "red");
    });
{/literal}
</script>
</head>
<body>
    User Information:<br />
    Name: {$name}
</body>
</html>

jQuery AJAX functions (load(), $.get(), etc.) are not loading new page versions problem

Today I would like to share with you a quick solution to the common problem when your AJAX calls to some page that changes over time is not being loaded to your page. In other words, jQuery or your browser is not loading new version of the page.

This problem is common in Mozilla Firefox (FF). Internet Explorer (IE) users I believe, do not experience this problem. Usually it occurs when you use jQuery AJAX functions in javascript setInterval() method. Basically, what happens is that Firefox can not see the changes been made to the page and thinks it’s the same with the old one. So Firefox loads it from cache and you don’t see the new version of your page. To resolve this issue, you should simply add a random string to the request like below.

The solution:

// Reload mypage.html every 5 seconds
var refresh = setInterval(function()
{
    // Minimized code, suggested by Kovacs
    $('#mydiv').load("mypage.htm?" + 1*new Date() );

}, 5000);

Dynamically creating input box/checkbox/radio button... does not work in Internet Explorer (IE)

While working on some project, trying to create a checkbox and radio button dynamically using jQuery I came across a problem. Mozilla Firefox, Opera and Safari were creating and rendering my new checkboxes just fine, but Internet Explorer (IE6, IE7) did not create them. I spend half a day trying to figure out what is wrong with my jQuery or JavaScript code. Some hours later, I remember, I came across a post saying that IE can not create a general DOM input form element and then assign it a type (checkbox, radio, text, password, etc) attribute.

What you need to do when you are creating a new checkbox or radio button set with jQuery is to define the type attribute while creating like so:

$('<input type="checkbox" />');
// Create and then set any other attributes
$('<input type="checkbox" />').attr('id', 'newBox');

Problem:

Can not create a new input form fields using jQuery or newly created checkboxes and radio buttons are not displayed/created.

Solution:

To solve the problem you need to create an input field with type attribute already defined.

Font cleartype problems with fadeIn() and fadeOut() in Internet Explorer 7 (IE7)

Have you ever noticed whenever you use jQuery's fadeIn() and fadeOut() functions your text will become edgy. Mozilla and other seem to be rendering fine (not sure about IE6). Anyway, to solve this problem you need to remove the filter attribute from the DOM element that you have faded in/out.

For example:

// This causes this text glich
$("#message").fadeIn();

// This will fix it
document.getElementById("#message").style.removeAttribute("filter");

Screenshots:

SS-20090216194727

SS-20090216194422 

You need to remove the filter attribute after fadeIn() function has completed its job. In other words, as a function callback. Otherwise, fadeIn()/fadeOut() functions would change the opacity of the element, which in turn would cause the filter attribute to be attached yet again. So, remove the attribute in function callback like this:

$('#message').fadeIn(function(){
    this.style.removeAttribute("filter");
});

How to set custom rules in jQuery Validation plugin for fields that have a period "." in their names

We all love and use jQuery Validation plugin. For basic forms it does a great job and works flawlessly 80% of the time. But we all work on different kinds of projects and validation requirements change project to project.

jQuery Validation is a very flexible plugin and provides a way to easily define your own validation rules. You can read more about jQuery Validation plugin and custom validation rules here. It is quite straight forward.

Anyway, I was working on a project that requires the use of custom rules and I had no control over the generated HTML code and used CSS selectors. So I had to work with CSS classes that had period "." symbol in their names. My first attempt failed.

Here is the code that failed. Pay attention to the selector name with the (.) in it's name.

rules: { 
    user.email: { 
        required: true, 
        email: true 
    } 
} 

It is common in Java programming world that your form fields have periods (.) in their names and this is an example of that. So to solve the problem all you have to do is to make the object key a string like this:

rules: { 
    "user.email": { 
        required: true, 
        email: true 
    } 
} 

This will solve your problem and let you get on with your project. Happy coding...

How to check your JavaScript code for errors

There are times when you can't understand why your code is not doing what it's supposed to do. After killing half an hour on trying to figure out what is the problem you either give up and decide to rewrite or leave it for later. Later looking at your code you clearly see the bug and think how you couldn't you see it.

For cases like that you can use online JavaScript code validator JSLint.

Access to restricted URI denied" code: "1012

This post will discuss and provide several solutions to "Access to restricted URI denied" error. This error is thrown in Firefox browser, while making AJAX request that does not comply with the browser's security policies.

The error occurs when application tries to do an AJAX request that does not comply with the same-origin policy or tries to access a local resource (file on your hard drive with a path like file://c:/Users/etc.). To solve this problem you need to change the URI to your files so that it appears as if they were on the same domain as the page your AJAX script is calling it from.

Let's try to reproduce the error.

$(document).ready(function(){

  // Try to load content from the hard drive
  $.get('file:///Users/path-to/seed-data.js', function(data){
    console.log(data);
  });

  // Try to load content from another domain
  $.ajax({
    url: "http://www.google.com/some-file.html",
  }).done(function(data) {
    console.log(data);
  });

  // Try to load content from the same domain, but different protocol
  // Assume we are on http://www.example.com page and trying to access
  // page on the same secure domain "https"
  $.get('https://www.example.com/seed-data.js', function(data){
    console.log(data);
  });

});

The examples above will result in the following error in your JavaScript console.

Access to restricted URI denied" code: "1012
xhr.open(type, s.url, s.async);

Reasons

  1. In the first example, the reason for the error is Firefox's security model that does not allow retrieving/accessing resources localhost resources.

  2. In the second example, Firefox enforced "same origin" security policy that does not allow accessing resources from other domains (NOTE: www.example.com and example.com are considered two different domains as well).

  3. In the third example, we tried to access resources using different protocol (https). Don't forget HTTP and HTTPS are two different protocols.

Solutions

In order to solve the "Access to restricted URI denied" error, you need to identify which of the reasons above is causing your script to throw an error and fix it with one of the solutions below.

  1. First problem: Deploy files to a web server or alternatively run one locally (ex. XAMPP). Once deployed, access your page from your domain (http://www.your-domain.com/page.html or http://localhost:port/page.html).

  2. To access resources from other domains you have to overcome the "same origin policy". This can be done by putting a simple proxy script on your own domain and it would appear as if you are fetching resources from your own domain. You can find description and an example proxy script in “Cross domain AJAX scripting” post.

  3. The solution to the last method is usually easy. In most cases it is either putting or removing "s" to/from "http". But for cases when you have to grab content from URL using different protocol, your only solution is to use proxy script described in the second solution.

If this post does not cover your case please leave a comment with reproducable code or a link to fiddle page. If you found this post helpful, please share/like it.