94 lines
No EOL
3.8 KiB
HTML
94 lines
No EOL
3.8 KiB
HTML
{% macro render_table(headers, rows, id, entry_route=None, title=None, per_page=15) %}
|
|
<!-- Table Fragment -->
|
|
|
|
{% if rows %}
|
|
{% if title %}
|
|
<label for="datatable-{{ id|default('table')|replace(' ', '-')|lower }}" class="form-label">{{ title }}</label>
|
|
{% endif %}
|
|
<div class="table-responsive">
|
|
<table id="datatable-{{ id|default('table')|replace(' ', '-')|lower }}"
|
|
class="table table-bordered table-sm table-hover table-striped table-light m-0{% if title %} caption-top{% endif %}">
|
|
<thead class="sticky-top">
|
|
<tr>
|
|
{% for h in headers %}
|
|
<th class="text-nowrap">{{ h }}</th>
|
|
{% endfor %}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for row in rows %}
|
|
<tr {% if entry_route %}onclick="window.location='{{ url_for('main.' + entry_route, id=row.id) }}'"
|
|
style="cursor: pointer;" {% endif %}{% if row['highlight'] %} class="table-info" {% endif %}>
|
|
{% for cell in row.cells %}
|
|
<td class="text-nowrap{% if cell.type=='bool' %} text-center{% endif %}">
|
|
{% if cell.type == 'bool' %}
|
|
{{ cell.html | safe }}
|
|
{% elif cell.url %}
|
|
<a class="link-success link-underline-opacity-0" href="{{ cell.url }}">{{ cell.text }}</a>
|
|
{% else %}
|
|
{{ cell.text or '-' }}
|
|
{% endif %}
|
|
</td>
|
|
{% endfor %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
new DataTable('#datatable-{{ id|default('table')|replace(' ', ' - ')|lower }}', {
|
|
pageLength: {{ per_page }},
|
|
scrollX: true,
|
|
scrollY: '60vh',
|
|
scrollCollapse: true,
|
|
})
|
|
})
|
|
</script>
|
|
{% else %}
|
|
<div class="container text-center">No data.</div>
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro dynamic_table(id, headers=none, fields=none, entry_route=None, title=None, page=1, per_page=15, offset=0,
|
|
refresh_url=none, model=none, sort=none) %}
|
|
<!-- Table Fragment -->
|
|
|
|
{% if title %}
|
|
<label for="datatable-{{ id|default('table')|replace(' ', '-')|lower }}" class="form-label">{{ title }}</label>
|
|
{% endif %}
|
|
<div class="table-responsive" id="table-container-{{ id }}" x-data='Table({
|
|
id: "{{ id }}",
|
|
refreshUrl: null,
|
|
headers: {{ headers|tojson if headers else "[]" }},
|
|
perPage: {{ per_page }},
|
|
offset: {{ offset if offset else 0 }},
|
|
fields: {{ fields|tojson if fields else "[]" }}
|
|
})'>
|
|
<table id="datatable-{{ id|default('table')|replace(' ', '-')|lower }}"
|
|
class="table table-bordered table-sm table-hover table-striped table-light m-0 caption-bottom">
|
|
<thead class="sticky-top">
|
|
<tr>
|
|
{% for h in headers %}
|
|
<th class="text-nowrap">{{ h }}</th>
|
|
{% endfor %}
|
|
</tr>
|
|
</thead>
|
|
<tbody id="rows"
|
|
hx-get="/ui/{{ model }}/frag/rows?page={{ page }}&per_page={{ per_page }}&fields_csv={{ fields|join(',') }}"
|
|
hx-trigger="load" hx-target="#rows" hx-swap="innerHTML"></tbody>
|
|
</table>
|
|
<div id="pager-state">
|
|
<input type="hidden" name="page" value="{{ page }}">
|
|
<input type="hidden" name="per_page" value="{{ per_page }}">
|
|
<input type="hidden" name="fields_csv" value="{{ fields|join(',') }}">
|
|
{% if sort %}<input type="hidden" name="sort" value="{{ sort }}">{% endif %}
|
|
{% for k,v in (filters or {}).items() %}
|
|
<input type="hidden" name="{{ k }}" value="{{ v }}">
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
<div id="pager" hx-get="/ui/{{ model }}/frag/pager" hx-include="#pager-state"
|
|
hx-trigger="load, htmx:afterSwap from:#rows" hx-target="#pager" hx-swap="innerHTML"></div>
|
|
{% endmacro %} |