fix htmx refresh messing with filter controls

This commit is contained in:
insects 2025-02-06 15:34:29 +01:00
parent c0e8081a19
commit 79047c87ff
3 changed files with 76 additions and 51 deletions

View file

@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc};
use axum::{
extract::{Path, Query, State},
http::StatusCode,
http::{HeaderMap, StatusCode},
response::{IntoResponse, Redirect, Response},
routing::{get, post},
Router,
@ -65,6 +65,7 @@ pub struct FilterQuery {
}
async fn main_handler(
headers: HeaderMap,
state: State<Arc<AppState>>,
Path(acc_id): Path<String>,
axum_extra::extract::Query(query): axum_extra::extract::Query<FilterQuery>,
@ -75,7 +76,10 @@ async fn main_handler(
}
let caught_fish = db::get_caught_fish(&acc_id, &state.pool).await?;
let filters = Filters::from_query(query);
Ok(templates::main_page(state, caught_fish, acc_id, &filters).into_response())
// If this is a HTMX-sent request, don't resend the entire page, just the list.
let is_htmx = headers.contains_key("HX-Request");
Ok(templates::main_page(state, caught_fish, acc_id, &filters, is_htmx).into_response())
}
async fn insert_cf_handler(

View file

@ -30,6 +30,7 @@ pub fn main_page(
caught_fish: Vec<i32>,
acc_id: String,
filters: &Filters,
only_list: bool,
) -> Markup {
let meta = state.data.fish_with_meta();
let mut values: Vec<&CombinedFish> = filters.filter(meta.values().collect(), &caught_fish);
@ -55,50 +56,8 @@ pub fn main_page(
// Ordering::Equal
// }
// });
let template = html! {
.header {
h1 { "Hello! Current ET: " (clock::get_current_eorzea_date().format("%H:%M")) }
.side {
details {
summary { "Filters" }
form {
fieldset {
@if filters.non_big_fish {
input name="big" id="big" type="checkbox" checked;
} @else {
input name="big" id="big" type="checkbox";
}
label for="big" { "Include non big fish?" }
}
fieldset {
@if filters.include_caught {
input name="caught" id="caught" type="checkbox" checked;
} @else {
input name="caught" id="caught" type="checkbox";
}
label for="caught" { "Include caught fish?" }
}
fieldset {
label for="patches" { "Filter by patch" }
br;
select name="patches" id="patches" multiple {
@for patch in data::PATCHES {
@if filters.patches.contains(&patch) {
option value=(patch) selected { (format!("{:.1}", patch)) }
} @else {
option value=(patch) { (format!("{:.1}", patch)) }
}
}
}
}
button type="submit" { "Apply" }
}
}
}
}
let list = html! {
h2.clock { "ET " (clock::get_current_eorzea_date().format("%H:%M")) }
@for fish in values {
section.up[fish.is_up].alwaysup[fish.is_always_up] {
.title {
@ -170,11 +129,64 @@ pub fn main_page(
}
};
layout(html! {
main hx-get="" hx-trigger="every 10s" {
(template)
let template = html! {
.header {
div {}
.side {
details {
summary { "Filters" }
form {
fieldset {
@if filters.non_big_fish {
input name="big" id="big" type="checkbox" checked;
} @else {
input name="big" id="big" type="checkbox";
}
label for="big" { "Include non big fish?" }
}
fieldset {
@if filters.include_caught {
input name="caught" id="caught" type="checkbox" checked;
} @else {
input name="caught" id="caught" type="checkbox";
}
label for="caught" { "Include caught fish?" }
}
fieldset {
label for="patches" { "Filter by patch" }
br;
select name="patches" id="patches" multiple {
@for patch in data::PATCHES {
@if filters.patches.contains(&patch) {
option value=(patch) selected { (format!("{:.1}", patch)) }
} @else {
option value=(patch) { (format!("{:.1}", patch)) }
}
}
}
}
button type="submit" { "Apply" }
}
}
}
}
})
div hx-get="" hx-trigger="every 10s" hx-swap="innerHTML" hx-target="this" {
(list)
}
};
if only_list {
list
} else {
layout(html! {
main {
(template)
}
})
}
}
pub fn root() -> Markup {

View file

@ -22,7 +22,7 @@ select {
}
.header h1 {
margin-top: 0;
margin: 0;
}
.title {
@ -119,3 +119,12 @@ li {
max-width: 50em;
line-height: 1.5rem;
}
h2.clock {
margin: 0;
margin-bottom: 5px;
}
summary:hover {
cursor: pointer;
}