A django-tables2 Column for status/tag fields with a Bootstrap popover header and colored badge cells. Cotton-friendly.
Project description
django-cotton-status
A django-tables2 Column that renders a status / tag field as a Bootstrap popover header (documenting each possible value) plus a colored badge in each cell — all from a single declaration.
Designed for projects using Django Cotton and Bootstrap 5.
What it gives you
from django_cotton_status import StatusColumn
class OrderTable(tables.Table):
status = StatusColumn(
label='Status',
items=[
{'value': 'PENDING', 'label': 'Pending', 'badge': 'warning', 'description': 'Awaiting confirmation.'},
{'value': 'SHIPPED', 'label': 'Shipped', 'badge': 'info', 'description': 'En route to customer.'},
{'value': 'DELIVERED','label': 'Delivered','badge': 'success', 'description': 'Customer received.'},
{'value': 'CANCELED', 'label': 'Canceled', 'badge': 'danger', 'description': 'Order canceled.'},
],
)
That single line gives you:
- A column header with an info icon. Hovering or focusing the icon shows a popover listing every possible status with its colored badge and description.
- Cells rendered as
<span class="badge rounded-pill bg-{color}">{label}</span>based on the row's value.
No more duplicated ESTADO_BADGE = {...} dicts and render_status methods scattered across your codebase. One list of items defines everything.
Requirements
- Python 3.10+
- Django 4.2+
- django-cotton 0.9+
- django-tables2 2.4+
- Bootstrap 5 on the client side (loaded by your project)
Installation
pip install django-cotton-status
Add to INSTALLED_APPS:
INSTALLED_APPS = [
# ...
'django_cotton',
'django_tables2',
'django_cotton_status',
]
Bootstrap popover initialization
Bootstrap 5 does not auto-initialize popovers — you need to call new bootstrap.Popover(el) per trigger. If your project uses HTMX, you also need to clean up and re-init on swap, otherwise orphaned popovers stay floating and freshly-swapped triggers stay dead.
Drop this once in your base template:
<script>
function cleanupPopovers() {
document.querySelectorAll('.popover').forEach(el => el.remove());
}
function initPopovers() {
cleanupPopovers();
document.querySelectorAll('[data-bs-toggle="popover"]').forEach(el => {
if (el._popover) {
el._popover.dispose();
el._popover = null;
}
el._popover = new bootstrap.Popover(el);
});
}
document.addEventListener('DOMContentLoaded', initPopovers);
document.body.addEventListener('htmx:beforeSwap', cleanupPopovers);
document.body.addEventListener('htmx:afterSettle', initPopovers);
window.addEventListener('beforeunload', cleanupPopovers);
</script>
htmx:afterSettle fires after HTMX swap animations finish, so new triggers are stable when initialized.
Usage
Main use case — StatusColumn
import django_tables2 as tables
from django_cotton_status import StatusColumn
ORDER_STATUSES = [
{'value': 'PENDING', 'label': 'Pending', 'badge': 'warning', 'description': 'Awaiting confirmation.'},
{'value': 'SHIPPED', 'label': 'Shipped', 'badge': 'info', 'description': 'En route to customer.'},
{'value': 'DELIVERED','label': 'Delivered','badge': 'success', 'description': 'Customer received.'},
{'value': 'CANCELED', 'label': 'Canceled', 'badge': 'danger', 'description': 'Order canceled.'},
]
class OrderTable(tables.Table):
status = StatusColumn(label='Status', items=ORDER_STATUSES)
class Meta:
model = Order
fields = ('status',)
If a row's value isn't in items, the cell falls back to the raw value (no badge).
Cotton component (outside tables)
For places that aren't a Column — detail page headers, cards, anywhere — use the cotton component:
<c-status-popover label="Status" :items="order_statuses" />
Same look, same data shape (without value, since there's nothing to match against).
Python helper (advanced)
If you build your own verbose_name and need just the popover string:
from django_cotton_status import info_popover
label_html = info_popover(
'Status',
items=[
{'badge': 'success', 'label': 'Approved', 'description': '...'},
{'badge': 'danger', 'label': 'Rejected', 'description': '...'},
],
)
# label_html is a Django SafeString — safe to inject into HTML attributes.
Item shape
{
'value': 'APPROVED', # required for StatusColumn cell rendering
'label': 'Approved', # visible chip text
'badge': 'success', # Bootstrap color name
'description': 'Approved order.', # popover body text
}
For the cotton component and info_popover(), the value field is optional (only used by StatusColumn to match the cell value).
Bootstrap colors supported: primary, secondary, success, danger, warning, info, light, dark.
Customization
Placement
status = StatusColumn(label='Status', items=..., placement='right')
Accepts any value Bootstrap supports: top, bottom, left, right, auto.
Icon
By default the trigger uses fas fa-circle-info (Font Awesome). Override:
# Bootstrap Icons
status = StatusColumn(label='Status', items=..., icon_class='bi bi-info-circle')
Status
Alpha. API may change before 1.0.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_cotton_status-0.2.0.tar.gz.
File metadata
- Download URL: django_cotton_status-0.2.0.tar.gz
- Upload date:
- Size: 11.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54402ffb7ab079f2d2274d2a97f73298d5ce7486bc16a6060d37d80c2ec06b77
|
|
| MD5 |
2ea67f5644af35d11c64bf4d4c7387fc
|
|
| BLAKE2b-256 |
64b680556e5719a6b03f17f475aedbc03f884cab69179af04a5cdef9a51a0016
|
File details
Details for the file django_cotton_status-0.2.0-py3-none-any.whl.
File metadata
- Download URL: django_cotton_status-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5fd90a0ce74114c2c3920b5851ad982c8925da7de8710c9c0acfb2ac07bacdb5
|
|
| MD5 |
522c193d96cef23b93834382caa65c22
|
|
| BLAKE2b-256 |
7f34101ab5c6350184ee4b040799d77597fdfbea487d62b1619ed6e95196351a
|