elky / django-flat-theme

A flat theme for Django admin interface. Modern, fresh, simple.
Other
413 stars 45 forks source link

Display of fields on the same line #25

Open andybak opened 9 years ago

andybak commented 9 years ago

From: https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets

As with the fields option, to display multiple fields on the same line, wrap those fields in their own tuple.

As you can see the labels are closer to the preceeding input than they are to their own: https://drive.google.com/file/d/0B_afp8i9IOxeNDZlcWZ5ZDdvTTg/view?usp=drivesdk

I think this was also an issue with the old admin css but now might be a good time to address it.

I'm not sure what the best fix is. However - it should be possible to target form-rows with multiple fields using a variant of this technique: http://stackoverflow.com/questions/8720931/can-css-detect-the-number-of-children-an-element-has

I suggest either:

  1. close the gap in this case
  2. add some form of divider between fields
andybak commented 9 years ago

I wonder if flexbox is a potential solution? We could combine that with the 'classes' parameter to fieldsets:

    fieldsets = (
        ("Something", {
            'fields': (('property', 'type'), ('from_date', 'to_date')),
            'classes': 'form-row-6columns',
        }),
    )

You could then set up a pseudo-table layout so that fields on the same row aligned in columns correctly even though they weren't in the same group of fields.

elky commented 9 years ago

@andybak The problem is that label has fixed width, so obvious solution is to add class for the row if fields declared as tuple, I believe. Then we can control label width to set it in auto. But it breaks the grid:

screenshot 2015-09-26 at 15 42 49

So what if we just add divider as you suggested? It's easy CSS fix.

screenshot 2015-09-26 at 15 44 30

Makes sense? The gap is still big between label and input but it looks less messy in terms of UX I think.

andybak commented 9 years ago

But it breaks the grid:

Is it really a grid once you have a few tuple rows? It just looks like a mess on most of my changeforms. If you have mostly single field rows and a couple of tuple rows then maybe having the first input field on each row lining up looks moderately neat but it breaks down fairly quickly. Look how two tuple rows next to each other looks:

screenshot-localhost 8000 2015-09-26 15-46-50

I'm trying to work out how a moderately complex form with a reasonable number of tuple rows could look better. Is it possible to get something closer to a real grid working where the 2nd and 3rd columns also line up with each other?

andybak commented 9 years ago

I'm making a bit of progress:

  1. Remove the fixed width from inputs (your grid should control this)
  2. Use padding instead of margin for .field-box so we can use box-sizing: border-box
  3. Set a width based on the number of columns you want (i.e. 20% is 5 columns)
  4. Tweak label padding and a few other things to be slightly less generous with white space.

As you can see - I get something fairly close to a grid layout. The read-only fields currently mess it up but that shouldn't be hard to fix:

screenshot-localhost 8000 2015-09-26 16-07-56

I'm not sure whether this is something that should be fixed in Django core right now but the fact that complex admin forms look a mess has been bothering me for a while. What are your thoughts?

andybak commented 9 years ago

Flexbox might make some of this a bit easier to handle - i.e. we would probably remove the need to mess around with margins and box-sizing.

andybak commented 9 years ago

I went the route of an explicit opt-in:

(" Status", {
    'fields': (('foo', bar'),),
    'classes': ('has-cols', 'cols-4',),
}),

This seems to work. I'm still testing but let me know if this is of any interest. I'll stop posting here if it's out of scope for your work.

fieldset.aligned.has-cols .form-row img, fieldset.aligned.has-cols .form-row input {
    width: 180px;
}

fieldset.aligned.has-cols .form-row input[type='checkbox'] {
    width: 12px;
    margin-right: 5px;
}

fieldset.aligned.has-cols .form-row p.help {
    margin-left: 120px;
    padding-left: 5px;
    color: #CCC;
    font-size: 12px;
}

fieldset.aligned.has-cols .form-row select {
    width: 194px;
}

fieldset.aligned.has-cols .form-row label {
    padding: 4px 3px 0 0;
    width: 120px;
}

fieldset.aligned.has-cols .form-row label + p {
    margin-left: 0;
}

fieldset.aligned.has-cols .form-row .field-box {
    margin-right: 0;
    padding-right: 10px;
    box-sizing: border-box;
}

fieldset.aligned.has-cols .form-row p.datetime {
    margin-left: 0;
    float: right;
}

fieldset.aligned.has-cols .form-row .datetime input.vDateField, fieldset.aligned.has-cols .form-row .datetime input.vTimeField {
    width: 70px;
}

fieldset.aligned.cols-2 .form-row .field-box {
    width: 50%;
}

fieldset.aligned.cols-3 .form-row .field-box {
    width: 33%;
}

fieldset.aligned.cols-4 .form-row .field-box {
    width: 25%;
}

fieldset.aligned.cols-5 .form-row .field-box {
    width: 20%;
}
andybak commented 9 years ago

Add this rule to get dividers:

fieldset.aligned.has-cols .form-row .field-box ~ .field-box {
    border-left: 1px dotted #CCC;
    margin-left: 6px;
    padding-left: 6px;
}
elky commented 8 years ago

@andybak looks good, I'll check this on one of my real projects

nyejon commented 6 years ago

Any updates on this?