Is there a way to make a collapsed inline initially visible in Django admin, if it has a value?

Viewed 39

I am programming a website builder in Django, and each page has lots of fields to fill out.

Some of them are pretty arcane, and to keep from cluttering up the page they are initially hidden:

class ScriptInlinePage(admin.TabularInline):
  model = Page.script.through
  extra = 0
  fields = ('active', 'script', 'order', )
  verbose_name = "script set"
  verbose_name_plural = "script sets"
  classes = ['collapse']

In the interests of streamlining the page, I have made it so that collapsed inlines are unobtrusive:

Script Sets (Show ▶)

However, these initially-hidden fields can have a disastrous effect if they contain a value and the user is unaware of it.

I am looking for a way to either:

  1. add a class collapsed but initially visible if not empty, or
  2. modify the collapse class so that it is only initially collapsed if it's empty

I have tried adding to models.py something like:

def is_empty:
  if self.count > 0: return True
  else: return False

but I don't know how to use this information in the Admin class to get the effect I want.

Similar question: I thought I saw a way to make an inline collapsible without making it initially collapsed, but after much googling I can't find it. Is that not a thing?

1 Answers

Thanks to A D who got me looking in the right place, I ended up copying the admin javascript that collapses the collapsed elements.

[app folder]/static/admin/js/ifempty.js

'use strict';
{
    window.addEventListener('load', function() {

        const fieldsets = document.querySelectorAll('fieldset.ifempty');
        for (const [i, elem] of fieldsets.entries()) {
            if (elem.querySelectorAll('div.related-widget-wrapper').length > 1) {
                elem.classList.remove('collapse');
            }
        }
    });
}

Then, in admin.py:

class PageAdmin(admin.ModelAdmin):
  class Media:
    js = ( 'admin/js/ifempty.js', )
    ...

The result is that in the inline, I can add ifempty to the class list:

class ScriptInlinePage(admin.TabularInline):
  model = Page.script.through
  extra = 0
  fields = ('active', 'script', 'order', )
  verbose_name = "script set"
  verbose_name_plural = "script sets"
  classes = ['collapse', 'ifempty',]

And when the page is loaded, "hidden" fields that have values are no longer hidden.

Initially I would have liked to make these fields collapsible, but I realized that users would never bother.

So, canceling the collapse class when the field contains data is a perfect solution.

Related