title: Using jquery to run code when django document is ready
body: <p>I am building a django admin site and am using javascript and jquery (2.0.3) to add some extra functionality to the forms.</p>
  
  <p>I am importing the scripts into my page like this:</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;html&gt;
      &lt;head&gt;
          &lt;script type="text/javascript" src="/static/admin/js/jquery.js"&gt;&lt;/script&gt;
          &lt;script type="text/javascript" src="/static/admin/js/jquery.init.js"&gt;&lt;/script&gt;
          &lt;script type="text/javascript" src="/static/project/js/project.js"&gt;&lt;/script&gt;
      &lt;/head&gt;
      &lt;!-- ... --&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>At first I placed the following code at the end of <code>project.js</code>:</p>
  
  <pre class="lang-js prettyprint-override"><code>function tryCustomiseForm() {
      // ...
  }
  
  $(document).ready(tryCustomiseForm); 
  </code></pre>
  
  <p>Unfortunately this results in an <code>Uncaught TypeError: undefined is not a function</code> exception on the last line.</p>
  
  <p>I then tried the alternative syntaxes of <a href="http://api.jquery.com/ready/" rel="nofollow"><code>ready()</code></a> without any more luck.</p>
  
  <p>Lastly I explored the <code>change_form.html</code> template and found this inline javascript:</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;script type="text/javascript"&gt;
      (function($) {
          $(document).ready(function() {
              $('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
          });
      })(django.jQuery);
  &lt;/script&gt;
  </code></pre>
  
  <p>I was able to modify it to suit my needs and now my <code>project.js</code> ends with:</p>
  
  <pre class="lang-js prettyprint-override"><code>(function($) {
      $(document).ready(function() {
          tryCustomiseForm();
      });
  })(django.jQuery);
  </code></pre>
  
  <p>While this results in the correct behaviour <em>I don't understand it</em>.</p>
  
  <p>This leads to my question: Why did my first approach fail? And what is the second approach doing?</p>