views:

687

answers:

3

In the same way you can add 'classes': ['collapse'] to one of your ModelAdmin fieldsets, I'd like to be able to have an Inline Model Admin be collapsible.

This ticket, Collapse in admin interface for inline related objects, discusses exactly what I want to accomplish. But in the mean time, what's the best work around while we wait for the next release?

FYI: I've come up with a solution, but I think a better one exists. I'll let the voting take care of it.

A: 

Here's how I solved it, but it feels too much like a hack (for a hack).

I used jQuery hosted from Google APIs to modify the DOM, taking advantage of Django's own 'show/hide' script. If you look at the html source of an admin page, the last script loaded is this:

<script type="text/javascript" src="/media/admin/js/admin/CollapsedFieldsets.js"></script>

The comments in that file gave me the idea: Leverage ModelAdmin media definitions to load my own dom-altering script.

from django.contrib import admin
from django.contrib.admin.sites import AdminSite
from myapp.models import *
import settings
media = settings.MEDIA_URL

class MyParticularModelAdmin(admin.ModelAdmin):
    # .....
    class Media:
          js = ('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js',
              media+'js/addCollapseToAllStackedInlines.js')
# .....

And then inside of the referenced javascript file:

// addCollapseToAllStackedInlines.js
$(document).ready(function() {
  $("div.inline-group").wrapInner("<fieldset class=\"module aligned collapse\"></fieldset>");
});

The end results only works on StackedInline, NOT TabularInline.

Off Rhoden
A: 

I came up with this solution using jQuery that works on TabularInline

var selector = "h2:contains('TITLE_OF_INLINE_BLOCK')";
$(selector).parent().addClass("collapsed");
$(selector).append(" (<a class=\"collapse-toggle\" id=\"customcollapser\" href=\"#\"> Show </a>)");
$("#customcollapser").click(function() {
    $(selector).parent().toggleClass("collapsed");
});
A: 

A couple of improvements on gerdemb's answer. Adds the 'Show' and 'Hide' text appropriately, and let's you specify the tabular inline names in a list beforehand:

$(document).ready(function(){
var tabNames = ['Inline Name 1', 'Inline Name 2', 'Inline Name 3'];
for (var x in tabNames)
{
    var selector = "h2:contains(" + tabNames[x] + ")";
    $(selector).parent().addClass("collapsed");
    $(selector).append(" (<a class=\"collapse-toggle\" id=\"customcollapser\""+ x + " href=\"#\"> Show </a>)");
};    
$(".collapse-toggle").click(function(e) {
    $(this).parent().parent().toggleClass("collapsed");
    var text = $(this).html();
    if (text==' Show ') {
        $(this).html(' Hide ');
        }
    else {
        $(this).html(' Show ');
    };
    e.preventDefault();
});
});
nosforz