Update Nov 23, 2013: I've written a little app (django-chosenadmin) that'll automatically add this to every app.
Quite some time ago, I ran across the chosen.js plugin for jQuery and Prototype (I'm using the jQuery flavor). My first thought upon seeing this was, "This would rock in Django's admin app." Yet for some reason, I didn't make that happen.
I maintain a project where about 10 people use the admin app extensively. They manage several apps that
have foreign keys to django's
User model. This works well enough, but there are a few thousand
user accounts. That makes the default
<select> elements fairly unwieldy, and the
<select multiple> widgets are just horrendous!
chosen.js plugin is fairly straighforward to install for the
admin. You'll first need to grab a copy of
chosen.js and (if you want to use them) the default CSS and sprite files.
I just grabbed the most current version from github.
My static files are organized as follows. Note that I put chosen's CSS & sprite
files in a subdirectory named
project_directory/ static/ css/ chosen/ chosen.css chosen-sprite.png js/ chosen.js
Now, you can override the admin app's
template (be sure to get a copy for your version of django. You can do this by putting your
own copy of the template in your project's templates directory (see your
For me, that looks like this:
project_directory/ templates/ admin/ change_form.html
In that template, there's an
extrahead block. At the bottom of that block, you need to include a
link to the plugin and the css file. Since this is a jQuery plugin, you'll also need to include a link to jQuery.
(Even though django's admin comes bundled with jQuery, it's namespaced, so to use a 3rd-party plugin, you need
your own copy of the library. See
Now, you can apply the chosen plugin to all
However, this has one unfortunate side effect. Django's admin app contains a custom multi-select widget,
that normally looks like this:
The chosen plugin dutifully mangles the custom widget, which is probably not what you want:
class on the elements to which it is applied. So, we need the
The only what I got that to work was to use
setTimeout. This is definitely a hack, and I'd love to see a more elegant
solution... but it works. So, the previous code to initialize the chosen plugin would be replaced with the following:
Now the plugin gets loaded about 1 second after the page is finished loading, so you get both the admin app's
custom multi-select widget and the
chosen.js plugin. There's a visible delay before the plugin gets loaded,
but you could tweak the second argument to minimize this somewhat. For my needs, the benefits of the more usable interface
<select> elements outweigh the cost of loading the plugin.