add sort functionality to table columns in ui

This commit is contained in:
Manuel Gugger 2023-01-06 16:12:51 +01:00
parent 7b4e2628b2
commit 77ec92f7eb
4 changed files with 43 additions and 30 deletions

View File

@ -18,7 +18,9 @@ pub struct Params {
page: Option<u64>,
entities_per_page: Option<u64>,
render_partial: Option<bool>,
search: Option<String>
search: Option<String>,
sort_by: Option<String>,
sort_order: Option<String>
}
pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
@ -50,6 +52,8 @@ pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
let search = params.search.clone().unwrap_or(String::new());
let db = data.get_db();
let sort_by = params.sort_by.clone().unwrap_or(view_model.primary_key.to_string());
let sort_order = params.sort_order.clone().unwrap_or(String::new());
let result = E::list(db, page, entities_per_page, &search).await;
match result {
Ok(res) => {
@ -76,11 +80,12 @@ pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
ctx.insert("entity_name", &entity_name);
ctx.insert("notifications", &notifications);
ctx.insert("page", &page);
ctx.insert("params", &entities_per_page);
ctx.insert("entities_per_page", &entities_per_page);
ctx.insert("render_partial", &render_partial);
ctx.insert("view_model", &ActixAdminViewModelSerializable::from(view_model.clone()));
ctx.insert("search", &search);
ctx.insert("sort_by", &sort_by);
ctx.insert("sort_order", &sort_order);
let body = TERA
.render("list.html", &ctx)

View File

@ -27,7 +27,7 @@
{% endfor %}
{% endif %}
</div>
<div class="fade-in">
<div>
{% block content %}
{% endblock content %}
</div>

View File

@ -3,10 +3,8 @@
<title>Actix Admin</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css"
integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://unpkg.com/htmx.org@1.7.0"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css">
<script src="https://unpkg.com/htmx.org@1.8.4"></script>
<script>
function checkAll(bx) {
@ -18,6 +16,17 @@
}
}
function sort_by(column) {
document.getElementById("sort_by").value = column;
current_sort_order = document.getElementById("sort_order").value;
if(current_sort_order == "asc") {
document.getElementById("sort_order").value = "desc";
} else {
document.getElementById("sort_order").value = "asc";
}
document.getElementById('search_form').submit();
}
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
@ -59,23 +68,4 @@
z-index: 6;
pointer-events: none
}
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.2s;
}
@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>

View File

@ -33,7 +33,7 @@
<p class="control has-icons-left has-icons-right">
<input class="input is-rounded" type="search" id="search" value="{{ search }}" name="search"
placeholder="Search"
hx-get="/admin/{{ entity_name }}/list?render_partial=true&entities_per_page={{ entities_per_page }}&page={{ page }}"
hx-get="/admin/{{ entity_name }}/list?render_partial=true&entities_per_page={{ entities_per_page }}&page={{ page }}&sort_by={{ sort_by }}&sort_order={{ sort_order }}"
hx-trigger="keyup changed delay:500ms, search" hx-target="#{{ entity_name }}table"
hx-indicator="#loading">
<span class="icon is-small is-left">
@ -45,8 +45,10 @@
</div>
<div class="column is-narrow">
<div>
<form hx-boost="true" hx-indicator="#loading">
<form id="search_form" hx-boost="true" hx-indicator="#loading">
<input type="hidden" value="{{ search }}" name="search">
<input type="hidden" id="sort_by" name="sort_by" value="{{ sort_by}}">
<input type="hidden" id="sort_order" name="sort_order" value="{{ sort_order }}">
<div class="select">
<div class="control has-icons-left has-icons-right">
<select class="select" name="entities_per_page" onchange="this.form.submit()">
@ -72,9 +74,25 @@
<th>
<input type="checkbox" onclick="checkAll(this)">
</th>
<th>{{ view_model.primary_key | title }}</th>
<th onclick="sort_by('{{ view_model.primary_key }}');" class="is-clickable">{{ view_model.primary_key | title }}
{% if sort_by == view_model.primary_key %}
{% if sort_order == "asc" %}
<i class="ml-1 fa-solid fa-caret-up"></i>
{% else %}
<i class="ml-1 fa-solid fa-caret-down"></i>
{% endif %}
{% endif %}
</th>
{% for model_field in view_model.fields -%}
<th>{{ model_field.field_name | split(pat="_") | join(sep=" ") | title }}</th>
<th onclick="sort_by('{{ model_field.field_name }}');" class="is-clickable">{{ model_field.field_name | split(pat="_") | join(sep=" ") | title }}
{% if sort_by == model_field.field_name %}
{% if sort_order == "asc" %}
<i class="ml-1 fa-solid fa-caret-up"></i>
{% else %}
<i class="ml-1 fa-solid fa-caret-down"></i>
{% endif %}
{% endif %}
</th>
{%- endfor %}
<th>
<!-- Edit Action -->