Thanks for this very helpful explanation.
Hello Joash Xu Your article is awosome. Is it possible to share detailed contents regarding base.html, views.py etc.
I'm trying to make the similier table, but, It's not working to see table at the moment.
I appreciate if you share whole files if possible.
Awesome post, thank you! A perfect integration of htmx, django-filter and django-tables.
With some minor changes also infinite scroll is possible:
Add a template rendering the table rows with the last row triggering the loading of more rows (google htmx infinite-scroll. I cant post links here???) . Add url parameter lazy=1 in hx-get to flag infinite scroll request:
{# templates/bootstrap_htmx_rows.html #}
{% load django_tables2 %}
{% load i18n %}
{% for row in table.paginated_rows %}
{% with lastrow=forloop.last %}
{% block table.tbody.row %}
<tr {{ row.attrs.as_html }} {% if lastrow and table.page.has_next %}hx-get="{% querystring table.prefixed_page_field=table.page.next_page_number "lazy"="1" %}" hx-trigger="revealed" hx-swap="afterend"{% endif %}>
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}</td>
{% endfor %}
</tr>
{% endblock table.tbody.row %}
{% endwith %}
{% empty %}
{% if table.empty_text %}
{% block table.tbody.empty_text %}
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
{% endblock table.tbody.empty_text %}
{% endif %}
{% endfor %}
Override the table.tbody block in bootstrap_htmx.html and make use of the row rednering template (plus clear pagination blocks):
{% block table.tbody %}
<tbody {{ table.attrs.tbody.as_html }}>
{% include 'bootstrap_tables_htmx_rows.html' %}
</tbody>
{% endblock table.tbody %}
{% block pagination.previous %}
{% endblock pagination.previous %}
{% block pagination.range %}
{% endblock pagination.range %}
{% block pagination.next %}
{% endblock pagination.next %}
In view check if htmx request is due to infinite scroll (lazy in request.GET) then only render rows. If htmx request is due to filter/sort update the render full table.
def get_template_names(self):
if self.request.htmx:
if "lazy" in self.request.GET:
# Render only rows
template_name = "bootstrap_tables_htmx_rows.html"
else:
# Render Full table
template_name = "product_table_partial.html"
else:
# Render full page
template_name = "product_table_htmx.html"
return template_name
Dear Joash Xu, Thank you! But, may I request you 2 things? folder structure of this project & syntax used to call the stylesheet inside html files? Also, 'product_htmx' inside ""- hx-get="{% url 'product_htmx' %}" "", is it right term?
I am completely new to application development and trying to develop data entry web app using django. I tried to make your solution run without any error, but the page is appearing blank rendering nothing. So need help.
Walt Winnert
Great article, thanks for that, really helpful! One thing to mention: Won't the search reset the ordering of the columns? Do you have any elegant ideas on how to solve this? I tried adding hx-push-url="true" to the column ordering htmx which kind of works but doesn't seem perfect to me.