add htmx search field

This commit is contained in:
Manuel Gugger 2022-07-29 17:53:59 +02:00
parent 1f88d67b76
commit 09b9845b3d
8 changed files with 99 additions and 53 deletions

View File

@ -18,7 +18,7 @@ pub async fn create_get<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
let actix_admin = data.get_actix_admin(); let actix_admin = data.get_actix_admin();
let view_model = actix_admin.view_models.get(&entity_name).unwrap(); let view_model = actix_admin.view_models.get(&entity_name).unwrap();
let mut model = ActixAdminModel::from(text); let model = ActixAdminModel::from(text);
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.insert("entity_names", &entity_names); ctx.insert("entity_names", &entity_names);

View File

@ -4,7 +4,6 @@ use tera::{Context};
use crate::TERA; use crate::TERA;
use crate::prelude::*; use crate::prelude::*;
use super::edit_get::edit_get;
pub async fn edit_post<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>( pub async fn edit_post<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
_req: HttpRequest, _req: HttpRequest,

View File

@ -9,12 +9,14 @@ use crate::ActixAdminViewModel;
use crate::ActixAdminModel; use crate::ActixAdminModel;
use crate::TERA; use crate::TERA;
const DEFAULT_ENTITIES_PER_PAGE: usize = 5; const DEFAULT_ENTITIES_PER_PAGE: usize = 10;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Params { pub struct Params {
page: Option<usize>, page: Option<usize>,
entities_per_page: Option<usize>, entities_per_page: Option<usize>,
render_partial: Option<bool>,
search: Option<String>
} }
pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>( pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
@ -32,6 +34,7 @@ pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
let entities_per_page = params let entities_per_page = params
.entities_per_page .entities_per_page
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE); .unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
let render_partial = params.render_partial.unwrap_or(false);
let db = data.get_db(); let db = data.get_db();
let result: (usize, Vec<ActixAdminModel>) = E::list(db, page, entities_per_page).await; let result: (usize, Vec<ActixAdminModel>) = E::list(db, page, entities_per_page).await;
@ -40,9 +43,12 @@ pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.insert("entity_names", &entity_names); ctx.insert("entity_names", &entity_names);
ctx.insert("entity_name", &entity_name);
ctx.insert("entities", &entities); ctx.insert("entities", &entities);
ctx.insert("page", &page); ctx.insert("page", &page);
ctx.insert("params", &entities_per_page);
ctx.insert("entities_per_page", &entities_per_page); ctx.insert("entities_per_page", &entities_per_page);
ctx.insert("render_partial", &render_partial);
ctx.insert("num_pages", &num_pages); ctx.insert("num_pages", &num_pages);
ctx.insert("view_model", &view_model); ctx.insert("view_model", &view_model);

View File

@ -1,3 +1,9 @@
{% if render_partial and render_partial == true %}
{% block content %}
{% endblock content %}
{% else %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -7,11 +13,14 @@
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css"> <link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
<script src="https://unpkg.com/htmx.org@1.7.0"></script> <script src="https://unpkg.com/htmx.org@1.7.0"></script>
<style type="text/css">
</style>
</head> </head>
<body> <body>
<main class="container"> <main class="container">
{% include "header.html" %} {% include "header.html" %}
<div> <div>
{% block content %} {% block content %}
{% endblock content %} {% endblock content %}
@ -20,3 +29,4 @@
</body> </body>
</html> </html>
{% endif %}

View File

@ -6,7 +6,7 @@
<div> <div>
{% for model_field in view_model.fields -%} {% for model_field in view_model.fields -%}
<label for="{{ model_field.field_name }}"> <label for="{{ model_field.field_name }}">
{{ model_field.field_name }} {{ model_field.field_name | split(pat="_") | join(sep=" ") | title }}
{% if model_field.select_list != "" %} {% if model_field.select_list != "" %}
<select name="{{ model_field.field_name }}" <select name="{{ model_field.field_name }}"
{% if model.errors | get(key=model_field.field_name, default="" ) !="" %} placeholder="Invalid" aria-invalid="true" {% endif %}> {% if model.errors | get(key=model_field.field_name, default="" ) !="" %} placeholder="Invalid" aria-invalid="true" {% endif %}>
@ -17,18 +17,19 @@
{% endif %} {% endif %}
{% for select_list_item in select_lists[model_field.field_name] -%} {% for select_list_item in select_lists[model_field.field_name] -%}
<option {% if select_list_item[0]==model.values | get(key=model_field.field_name, default="" ) %} <option {% if select_list_item[0]==model.values | get(key=model_field.field_name, default="" ) %}
selected {% endif %} value="{{ select_list_item[0] }}">{{ select_list_item[1] }}</option> selected {% endif %} value="{{ select_list_item[0] }}">{{ select_list_item[1] | split(pat="_") | join(sep=" ") | title }}</option>
{%- endfor %} {%- endfor %}
</select> </select>
</label> </label>
{% else %} {% else %}
<input type="{{ model_field.html_input_type }}" <input type="{{ model_field.html_input_type }}"
value="{{ model.values | get(key=model_field.field_name, default="") }}" value="{{ model.values | get(key=model_field.field_name, default="") | split(pat="_") | join(sep=" ") | title }}"
name="{{ model_field.field_name }}" placeholder="{{ model_field.field_name }}" name="{{ model_field.field_name }}" placeholder="{{ model_field.field_name }}"
aria-label="{{ model_field.field_name }}"> aria-label="{{ model_field.field_name }}"
{% if model.errors | get(key=model_field.field_name, default="") != "" %} {% if model.errors | get(key=model_field.field_name, default="") != "" %}
placeholder="Invalid" aria-invalid="true" placeholder="Invalid" aria-invalid="true"
{% endif %} {% endif %}
>
{% endif %} {% endif %}
</label> </label>
{%- endfor %} {%- endfor %}

View File

@ -5,7 +5,7 @@
</ul> </ul>
<ul> <ul>
{% for entity_name in entity_names -%} {% for entity_name in entity_names -%}
<li><a href="/admin/{{ entity_name }}/list" class="secondary">{{ entity_name }}</a></li> <li><a href="/admin/{{ entity_name }}/list" class="secondary">{{ entity_name | title }}</a></li>
{%- endfor %} {%- endfor %}
</ul> </ul>
</nav> </nav>

View File

@ -2,58 +2,87 @@
{% block content %} {% block content %}
{% if not render_partial or render_partial == false %}
<article> <article>
<div class="grid"> <div class="grid">
<div> <div>
<a href="create" role="button">&#43;</a> <a href="create" role="button">Create</a>
</div>
<!--
<div>
<details role="list">
<summary aria-haspopup="listbox" role="button">
With selected
</summary>
<ul role="listbox">
<li><a>Delete</a></li>
</ul>
</details>
</div>-->
<div>
<input type="search" id="search" name="search" placeholder="Search"
hx-get="/admin/{{ entity_name }}/list?render_partial=true&entities_per_page={{ entities_per_page }}&page={{ page }}"
hx-trigger="keyup changed delay:500ms, search" hx-target="#{{ entity_name }}table"
>
</div> </div>
</div> </div>
<table role="grid"> <figure id="{{ entity_name }}table">
<thead> {% endif %}
<tr> <table role="grid">
<th>{{ view_model.primary_key }}</th> <thead>
{% for model_field in view_model.fields -%} <tr>
<th>{{ model_field.field_name }}</th> <th>
{%- endfor %} <!-- Select Checkbox -->
<th> </th>
<!-- Edit Action --> <th>{{ view_model.primary_key | title }}</th>
<!-- Delete Action --> {% for model_field in view_model.fields -%}
</th> <th>{{ model_field.field_name | split(pat="_") | join(sep=" ") | title }}</th>
</tr>
</thead>
<tbody hx-confirm="Are you sure?" hx-target="closest tr" hx-swap="outerHTML">
{% for entity in entities -%}
<tr>
<td>{{ entity.primary_key }}</td>
{% for model_field in view_model.fields -%}
<td>{{ entity.values | get(key=model_field.field_name) }}</td>
{%- endfor %}
<td>
<a href="edit/{{ entity.primary_key }}">&#9998;</a>
<a href="#" hx-post="delete/{{ entity.primary_key }}">&#128465;</a>
</td>
</tr>
{%- endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="{{ view_model.fields | length + 2 }}">
<a href="?page={{ page - 1 }}&entities_per_page={{ entities_per_page }}">&laquo;</a>
{% for i in range(end=num_pages) %}
<a href="?page={{ i + 1 }}&entities_per_page={{ entities_per_page }}">{{ i + 1 }}</a>
{%- endfor %} {%- endfor %}
<a href="?page={{ page + 1 }}&entities_per_page={{ entities_per_page }}">&raquo;</a> <th>
</td> <!-- Edit Action -->
</tr> <!-- Delete Action -->
</tfoot> </th>
</table> </tr>
</thead>
<tbody hx-confirm="Are you sure?" hx-target="closest tr" hx-swap="outerHTML">
{% for entity in entities -%}
<tr>
<td><input type="checkbox" id="entity{{ entity.primary_key }}" name="terms"></td>
<td>{{ entity.primary_key }}</td>
{% for model_field in view_model.fields -%}
<td>{{ entity.values | get(key=model_field.field_name) }}</td>
{%- endfor %}
<td>
<a href="edit/{{ entity.primary_key }}">&#9998;</a>
<a href="#" hx-post="delete/{{ entity.primary_key }}">&#128465;</a>
</td>
</tr>
{%- endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="{{ view_model.fields | length + 3 }}">
<a href="?page={{ page - 1 }}&entities_per_page={{ entities_per_page }}">&laquo;</a>
{% for i in range(end=num_pages) %}
<a href="?page={{ i + 1 }}&entities_per_page={{ entities_per_page }}">{{ i + 1 }}</a>
{%- endfor %}
<a href="?page={{ page + 1 }}&entities_per_page={{ entities_per_page }}">&raquo;</a>
</td>
</tr>
</tfoot>
</table>
{% if not render_partial or render_partial == false %}
</figure>
<div class="grid"> <div class="grid">
<div></div>
<div></div>
<div></div>
<div> <div>
<form> <form>
<label for="entities_per_page">Entities per Page <label for="entities_per_page">Entities per Page
<select name="entities_per_page" onchange="this.form.submit()"> <select name="entities_per_page" onchange="this.form.submit()">
{% for a in [10,20,50,100,] %} {% for a in [10,20,50,100,] %}
<option {% if entities_per_page == a %}selected{% endif %} value="{{ a }}">{{ a }}</option> <option {% if entities_per_page==a %}selected{% endif %} value="{{ a }}">{{ a }}</option>
{% endfor %} {% endfor %}
</select> </select>
</label> </label>
@ -61,4 +90,5 @@
</div> </div>
</div> </div>
</article> </article>
{% endif %}
{% endblock content %} {% endblock content %}

Binary file not shown.