Using jquery to run code when django document is ready
I am building a django admin site and am using javascript and jquery (2.0.3) to add additional functionality to forms.
I am importing scripts to my page like this:
<html>
<head>
<script type="text/javascript" src="/static/admin/js/jquery.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
<script type="text/javascript" src="/static/project/js/project.js"></script>
</head>
<!-- ... -->
</html>
First, I put the following code at the end project.js
:
function tryCustomiseForm() {
// ...
}
$(document).ready(tryCustomiseForm);
Unfortunately this results in an exception Uncaught TypeError: undefined is not a function
on the last line.
I then tried alternative syntaxes ready()
with no extra luck.
Finally, I researched the template change_form.html
and found this inline javascript:
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
});
})(django.jQuery);
</script>
I was able to change it to suit my needs and now mine project.js
ends with:
(function($) {
$(document).ready(function() {
tryCustomiseForm();
});
})(django.jQuery);
As long as this leads to the correct behavior, I don't get it.
This leads to my question: why did my first approach fail? And what is the second approach?
It's hard to tell from the code you posted, but it looks like the variable is $
not assigned by jQuery in your template; therefore the design $()
generated an error undefined function
.
The reason the latter works is because it closes your DOMReady handler that goes into django.jQuery
, which I assume is a noConflict
jQuery assigned variable from your template, and assigns it $
within the scope of that:
(function($) { // < start of closure
// within this block, $ = django.jQuery
$(document).ready(function() {
tryCustomiseForm();
});
})(django.jQuery); // passes django.jQuery as parameter to closure block
The Django docs explains this : jQuery is a namespace, so you can use django.jQuery
to refer to it in your admin template.
try
$(document).ready(function(){
tryCustomiseForm();
});
function tryCustomiseForm() {
// ...
}