<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang=""> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>JavaScript — Django 1.11.20 documentation</title> <link rel="stylesheet" href="../../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" /> <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script> <script type="text/javascript" src="../../../_static/jquery.js"></script> <script type="text/javascript" src="../../../_static/underscore.js"></script> <script type="text/javascript" src="../../../_static/doctools.js"></script> <script type="text/javascript" src="../../../_static/language_data.js"></script> <link rel="index" title="Index" href="../../../genindex.html" /> <link rel="search" title="Search" href="../../../search.html" /> <link rel="next" title="Writing documentation" href="../writing-documentation.html" /> <link rel="prev" title="Working with Git and GitHub" href="working-with-git.html" /> <script type="text/javascript" src="../../../templatebuiltins.js"></script> <script type="text/javascript"> (function($) { if (!django_template_builtins) { // templatebuiltins.js missing, do nothing. return; } $(document).ready(function() { // Hyperlink Django template tags and filters var base = "../../../ref/templates/builtins.html"; if (base == "#") { // Special case for builtins.html itself base = ""; } // Tags are keywords, class '.k' $("div.highlight\\-html\\+django span.k").each(function(i, elem) { var tagname = $(elem).text(); if ($.inArray(tagname, django_template_builtins.ttags) != -1) { var fragment = tagname.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>"); } }); // Filters are functions, class '.nf' $("div.highlight\\-html\\+django span.nf").each(function(i, elem) { var filtername = $(elem).text(); if ($.inArray(filtername, django_template_builtins.tfilters) != -1) { var fragment = filtername.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>"); } }); }); })(jQuery); </script> </head><body> <div class="document"> <div id="custom-doc" class="yui-t6"> <div id="hd"> <h1><a href="../../../index.html">Django 1.11.20 documentation</a></h1> <div id="global-nav"> <a title="Home page" href="../../../index.html">Home</a> | <a title="Table of contents" href="../../../contents.html">Table of contents</a> | <a title="Global index" href="../../../genindex.html">Index</a> | <a title="Module index" href="../../../py-modindex.html">Modules</a> </div> <div class="nav"> « <a href="working-with-git.html" title="Working with Git and GitHub">previous</a> | <a href="../../index.html" title="Django internals" accesskey="U">up</a> | <a href="../writing-documentation.html" title="Writing documentation">next</a> »</div> </div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> <div class="yui-g" id="internals-contributing-writing-code-javascript"> <div class="section" id="s-javascript"> <span id="javascript"></span><h1>JavaScript<a class="headerlink" href="#javascript" title="Permalink to this headline">¶</a></h1> <p>While most of Django core is Python, the <code class="docutils literal notranslate"><span class="pre">admin</span></code> and <code class="docutils literal notranslate"><span class="pre">gis</span></code> contrib apps contain JavaScript code.</p> <p>Please follow these coding standards when writing JavaScript code for inclusion in Django.</p> <div class="section" id="s-code-style"> <span id="code-style"></span><h2>Code style<a class="headerlink" href="#code-style" title="Permalink to this headline">¶</a></h2> <ul class="simple"> <li>Please conform to the indentation style dictated in the <code class="docutils literal notranslate"><span class="pre">.editorconfig</span></code> file. We recommend using a text editor with <a class="reference external" href="http://editorconfig.org/">EditorConfig</a> support to avoid indentation and whitespace issues. Most of the JavaScript files use 4 spaces for indentation, but there are some exceptions.</li> <li>When naming variables, use <code class="docutils literal notranslate"><span class="pre">camelCase</span></code> instead of <code class="docutils literal notranslate"><span class="pre">underscore_case</span></code>. Different JavaScript files sometimes use a different code style. Please try to conform to the code style of each file.</li> <li>Use the <a class="reference external" href="http://jshint.com/">JSHint</a> code linter to check your code for bugs and style errors. JSHint will be run when you run the JavaScript tests. We also recommended installing a JSHint plugin in your text editor.</li> <li>Where possible, write code that will work even if the page structure is later changed with JavaScript. For instance, when binding a click handler, use <code class="docutils literal notranslate"><span class="pre">$('body').on('click',</span> <span class="pre">selector,</span> <span class="pre">func)</span></code> instead of <code class="docutils literal notranslate"><span class="pre">$(selector).click(func)</span></code>. This makes it easier for projects to extend Django’s default behavior with JavaScript.</li> </ul> </div> <div class="section" id="s-javascript-patches"> <span id="s-id1"></span><span id="javascript-patches"></span><span id="id1"></span><h2>JavaScript patches<a class="headerlink" href="#javascript-patches" title="Permalink to this headline">¶</a></h2> <p>Django’s admin system leverages the jQuery framework to increase the capabilities of the admin interface. In conjunction, there is an emphasis on admin JavaScript performance and minimizing overall admin media file size. Serving compressed or “minified” versions of JavaScript files is considered best practice in this regard.</p> <p>To that end, patches for JavaScript files should include both the original code for future development (e.g. <code class="docutils literal notranslate"><span class="pre">foo.js</span></code>), and a compressed version for production use (e.g. <code class="docutils literal notranslate"><span class="pre">foo.min.js</span></code>). Any links to the file in the codebase should point to the compressed version.</p> <div class="section" id="s-compressing-javascript"> <span id="compressing-javascript"></span><h3>Compressing JavaScript<a class="headerlink" href="#compressing-javascript" title="Permalink to this headline">¶</a></h3> <p>To simplify the process of providing optimized JavaScript code, Django includes a handy Python script which should be used to create a “minified” version. To run it:</p> <div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> pip install closure <span class="gp">$</span> python django/contrib/admin/bin/compress.py </pre></div> </div> <p>Behind the scenes, <code class="docutils literal notranslate"><span class="pre">compress.py</span></code> is a front-end for Google’s <a class="reference external" href="https://developers.google.com/closure/compiler/">Closure Compiler</a> which is written in Java. The Closure Compiler library is not bundled with Django, but you can install it using pip as done above. The Closure Compiler library requires <a class="reference external" href="https://www.java.com">Java</a> 7 or higher.</p> <p>Please don’t forget to run <code class="docutils literal notranslate"><span class="pre">compress.py</span></code> and include the <code class="docutils literal notranslate"><span class="pre">diff</span></code> of the minified scripts when submitting patches for Django’s JavaScript.</p> </div> </div> <div class="section" id="s-javascript-tests"> <span id="s-id2"></span><span id="javascript-tests"></span><span id="id2"></span><h2>JavaScript tests<a class="headerlink" href="#javascript-tests" title="Permalink to this headline">¶</a></h2> <p>Django’s JavaScript tests can be run in a browser or from the command line. The tests are located in a top level <code class="docutils literal notranslate"><span class="pre">js_tests</span></code> directory.</p> <div class="section" id="s-writing-tests"> <span id="writing-tests"></span><h3>Writing tests<a class="headerlink" href="#writing-tests" title="Permalink to this headline">¶</a></h3> <p>Django’s JavaScript tests use <a class="reference external" href="https://qunitjs.com/">QUnit</a>. Here is an example test module:</p> <div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="nx">module</span><span class="p">(</span><span class="s1">'magicTricks'</span><span class="p">,</span> <span class="p">{</span> <span class="nx">beforeEach</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">$</span> <span class="o">=</span> <span class="nx">django</span><span class="p">.</span><span class="nx">jQuery</span><span class="p">;</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'#qunit-fixture'</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="s1">'<button class="button"></button>'</span><span class="p">);</span> <span class="p">}</span> <span class="p">});</span> <span class="nx">test</span><span class="p">(</span><span class="s1">'removeOnClick removes button on click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">assert</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">$</span> <span class="o">=</span> <span class="nx">django</span><span class="p">.</span><span class="nx">jQuery</span><span class="p">;</span> <span class="nx">removeOnClick</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">);</span> <span class="nx">assert</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span><span class="p">);</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">click</span><span class="p">();</span> <span class="nx">assert</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">);</span> <span class="p">});</span> <span class="nx">test</span><span class="p">(</span><span class="s1">'copyOnClick adds button on click'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">assert</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">$</span> <span class="o">=</span> <span class="nx">django</span><span class="p">.</span><span class="nx">jQuery</span><span class="p">;</span> <span class="nx">copyOnClick</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">);</span> <span class="nx">assert</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span><span class="p">);</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">click</span><span class="p">();</span> <span class="nx">assert</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">2</span><span class="p">);</span> <span class="p">});</span> </pre></div> </div> <p>Please consult the QUnit documentation for information on the types of <a class="reference external" href="https://api.qunitjs.com/assert/">assertions supported by QUnit</a>.</p> </div> <div class="section" id="s-running-tests"> <span id="running-tests"></span><h3>Running tests<a class="headerlink" href="#running-tests" title="Permalink to this headline">¶</a></h3> <p>The JavaScript tests may be run from a web browser or from the command line.</p> <div class="section" id="s-testing-from-a-web-browser"> <span id="testing-from-a-web-browser"></span><h4>Testing from a web browser<a class="headerlink" href="#testing-from-a-web-browser" title="Permalink to this headline">¶</a></h4> <p>To run the tests from a web browser, open up <code class="docutils literal notranslate"><span class="pre">js_tests/tests.html</span></code> in your browser.</p> <p>To measure code coverage when running the tests, you need to view that file over HTTP. To view code coverage:</p> <ul class="simple"> <li>Execute <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-m</span> <span class="pre">http.server</span></code> (or <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-m</span> <span class="pre">SimpleHTTPServer</span></code> on Python 2) from the root directory (not from inside <code class="docutils literal notranslate"><span class="pre">js_tests</span></code>).</li> <li>Open <a class="reference external" href="http://localhost:8000/js_tests/tests.html">http://localhost:8000/js_tests/tests.html</a> in your web browser.</li> </ul> </div> <div class="section" id="s-testing-from-the-command-line"> <span id="testing-from-the-command-line"></span><h4>Testing from the command line<a class="headerlink" href="#testing-from-the-command-line" title="Permalink to this headline">¶</a></h4> <p>To run the tests from the command line, you need to have <a class="reference external" href="https://nodejs.org/">Node.js</a> installed.</p> <p>After installing <cite>Node.js</cite>, install the JavaScript test dependencies by running the following from the root of your Django checkout:</p> <div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> npm install </pre></div> </div> <p>Then run the tests with:</p> <div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> npm <span class="nb">test</span> </pre></div> </div> </div> </div> </div> </div> </div> </div> </div> <div class="yui-b" id="sidebar"> <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> <div class="sphinxsidebarwrapper"> <h3><a href="../../../contents.html">Table of Contents</a></h3> <ul> <li><a class="reference internal" href="#">JavaScript</a><ul> <li><a class="reference internal" href="#code-style">Code style</a></li> <li><a class="reference internal" href="#javascript-patches">JavaScript patches</a><ul> <li><a class="reference internal" href="#compressing-javascript">Compressing JavaScript</a></li> </ul> </li> <li><a class="reference internal" href="#javascript-tests">JavaScript tests</a><ul> <li><a class="reference internal" href="#writing-tests">Writing tests</a></li> <li><a class="reference internal" href="#running-tests">Running tests</a><ul> <li><a class="reference internal" href="#testing-from-a-web-browser">Testing from a web browser</a></li> <li><a class="reference internal" href="#testing-from-the-command-line">Testing from the command line</a></li> </ul> </li> </ul> </li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="working-with-git.html" title="previous chapter">Working with Git and GitHub</a></p> <h4>Next topic</h4> <p class="topless"><a href="../writing-documentation.html" title="next chapter">Writing documentation</a></p> <div role="note" aria-label="source link"> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../../../_sources/internals/contributing/writing-code/javascript.txt" rel="nofollow">Show Source</a></li> </ul> </div> <div id="searchbox" style="display: none" role="search"> <h3>Quick search</h3> <div class="searchformwrapper"> <form class="search" action="../../../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <h3>Last update:</h3> <p class="topless">Feb 11, 2019</p> </div> </div> <div id="ft"> <div class="nav"> « <a href="working-with-git.html" title="Working with Git and GitHub">previous</a> | <a href="../../index.html" title="Django internals" accesskey="U">up</a> | <a href="../writing-documentation.html" title="Writing documentation">next</a> »</div> </div> </div> <div class="clearer"></div> </div> </body> </html>