Difficulty with Django and jQuery (why is $ undefined in the admin app?)
It's been a while since I worked with jQuery; I think I'm making a stupid mistake.
Here is a Django widget:
class FooWidget(Widget):
# ...
class Media:
js = ('js/foowidget.js',)
Here is the .js file:
alert("bar");
$(document).ready(function() {
alert("omfg");
$('.foo-widget').click(function() {
alert("hi");
return false;
});
});
alert("foo");
The only开发者_开发百科 alert()
that fires is the first. Do I have a stupid syntax error or something?
Also, if some other included script on the page redefines $(document).ready
, do I have to worry about it? I'm guessing that subsequent definitions will override mine, so it's safer for subsequent definitions to do something like:
$(document).ready(function() {
document.ready()
// real stuff
});
jQuery is already included in the page by the time foowidget.js
is.
Update: Based on @lazerscience's link, I tried the following instead, but it still fails just as before:
alert("bar");
$(function() {
alert("omfg");
$(".set-widget").click(function() {
alert("hi");
return false;
});
});
alert("foo");
Update 2: Curiously, when I do:
alert($);
I get "undefined". This suggests that jQuery is actually not initialized. This confuses me, because the <head>
includes:
<script type="text/javascript" src="/media/js/jquery.min.js"></script>
<script type="text/javascript" src="/media/js/jquery.init.js"></script>
<script type="text/javascript" src="/media/js/actions.min.js"></script>
<script type="text/javascript" src="/static/js/foowidget.js"></script>
Doesn't putting my script after the jQuery scripts ensure that $
will be defined?
Update 3: from jquery.min.js:
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i? /* ... */
Looks correct to me.
This is from the Firebug console:
Error: $ is not a function
[Break On This Error] $(function() {
foowidget.js (line 5)
>>> $
anonymous()
>>> jQuery
undefined
>>> $('a')
null
>>> $(document)
null
Update 4: $
is defined on all page of my Django site except the admin app. Odd...
Update 5: This is interesting.
jQuery.init.js:
// Puts the included jQuery into our own namespace
var django = {
"jQuery": jQuery.noConflict(true)
};
From the console:
>>> $
anonymous()
>>> django
Object {}
>>> django.jQuery
function()
>>> django.jQuery('a')
[a /admin/p..._change/, a /admin/logout/, a ../../, a ../, a.addlink add/]
Adding this to the top of my .js file fixes it:
var $ = django.jQuery;
I'm not sure how to remove the jquery.init.js file, given that my project doesn't contain any scripts that use $
for something other than jQuery.
i solved this problem on this way, you have to include jquery.init.js (often its jquery.init.js from admin) in this file add following lines:
var django = {
"jQuery": jQuery.noConflict(true)
};
var jQuery = django.jQuery;
var $=jQuery;
and u have in whole workspace jquery and $. For better code looking i prefer create my own jquery init file in project.
Use the Firebug or Web Inspector JS console and type $
and/or jQuery
. That's the simplest way to find out if the library has been loaded correctly. In the unlikely case, that only jQuery is defined, you can wrap your script into it's own scope:
(function($){
// your code here…
})(jQuery);
If nothing is defined at the console, the problem is most likely with the file and I'd try AndiDog's approach to see if there's anything loaded at all.
You can use $(document).ready()
as often as you want to on one page. It doesn't redefine anything as you call it, but the call of ready()
adds functions that are called when "the document is ready".
To debug your code eg. use Firebug that will show you more detailled information about where the error occurs if there's any!
In django one reason for this problem when you are using import_export plugin. In that case follow these steps -
- Create a folder under admin template directory named import_export (templates/admin/import_export)
- Create a file there named base.html (templates/admin/import_export/base.html)
type the below code base.html file.
{% extends "admin/import_export/base.html" %} {% load static %} {% block extrahead %} {{ block.super }} static/admin/js/vendor/jquery/jquery.js static/admin/js/jquery.init.js
{% endblock %}
In Firefox, view the source code of the page, then click the link "/media/js/jquery.min.js" to see whether it loaded. Most probably you're getting a 404 because you didn't define the media URL correctly.
You can also use the development server for this purpose, it will show you all requests and the HTTP status code returned.
I wrapped my js code to use jQuery:
window.onload = function () {
if (django.jQuery('body').hasClass('change-list')) {
....
}
}
You probably forgot to include {{ form.media }}
in your template.
精彩评论