first part done: re-filling the previous values, and global errors

This commit is contained in:
Artemis 2025-01-24 15:28:09 +01:00
parent 2bf185b1af
commit cb2c7af03d
8 changed files with 106 additions and 61 deletions

View file

@ -123,7 +123,8 @@ section {
margin-top: 2em;
}
p.form-error {
p.form-error,
div.form-error {
background-color: var(--clr-error-surface);
border: 2pt solid var(--clr-error-primary-0);
color: var(--clr-error-primary-40);
@ -131,6 +132,11 @@ p.form-error {
padding: .5em 1em;
}
.form-error>h4 {
margin: 0;
margin-top: .5em;
}
.split {
display: flex;
flex-direction: row;
@ -164,6 +170,10 @@ div.dual-fields {
margin-left: 1em;
}
p.heading {
margin-top: 0;
}
.raised {
background-color: var(--clr-surface-tonal-a10);
padding: 1em;

View file

@ -37,7 +37,7 @@ fn rocket() -> _ {
public::index,
public::show_profile,
form::register_tag::show_register,
form::register_tag::handle_register
form::register_tag::handle_register,
],
)
}

View file

@ -20,7 +20,8 @@ pub async fn show_register(db: DollTagsDb) -> PageResult {
Ok(Template::render(
"register",
context! {
ids
ids,
previous: form::Context::default(),
},
)
.into())
@ -33,27 +34,27 @@ pub struct TagForm<'a> {
#[field(validate=len(..32))]
pub microchip_id: &'a str,
#[field(validate=len(..256))]
#[field(validate=len(1..=256))]
pub name: &'a str,
#[field(validate=len(..32))]
#[field(validate=len(1..=32))]
pub pronoun_subject: &'a str,
#[field(validate=len(..32))]
#[field(validate=len(1..=32))]
pub pronoun_object: &'a str,
#[field(validate=len(..32))]
#[field(validate=len(1..=32))]
pub pronoun_possessive: &'a str,
#[field(validate=len(..256))]
#[field(validate=len(1..=256))]
pub handler_name: &'a str,
#[field(validate=len(..2048))]
#[field(validate=len(..=2048))]
pub handler_link: &'a str,
#[field(validate=len(..256))]
#[field(validate=len(..=256))]
pub kind: &'a str,
#[field(validate=len(..256))]
#[field(validate=len(..=256))]
pub breed: &'a str,
#[field(validate=len(..256))]
#[field(validate=len(..=256))]
pub behaviour: &'a str,
#[field(validate=len(..2048))]
#[field(validate=len(..=2048))]
pub description: &'a str,
#[field(validate=validate_chassis(self.chassis_id, self.chassis_color, "chassis_type"))]
@ -75,11 +76,11 @@ fn validate_id<'v>(id: &str) -> form::Result<'v, ()> {
fn validate_chassis<'v>(a: &str, b: &str, c: &str, field: &str) -> form::Result<'v, ()> {
let all_empty = a.len() == 0 && b.len() == 0 && c.len() == 0;
let all_full = a.len() != 0
&& a.len() < 256
&& a.len() <= 256
&& b.len() != 0
&& b.len() < 256
&& b.len() <= 256
&& c.len() != 0
&& c.len() < 256;
&& c.len() <= 256;
if !all_empty && !all_full {
Err(form::Error::validation(format!(
@ -92,7 +93,29 @@ fn validate_chassis<'v>(a: &str, b: &str, c: &str, field: &str) -> form::Result<
}
#[post("/register", data = "<tag>")]
pub async fn handle_register(mut db: DollTagsDb, tag: Form<TagForm<'_>>) -> PageResult {
pub async fn handle_register(
mut db: DollTagsDb,
tag: Form<Contextual<'_, TagForm<'_>>>,
) -> PageResult {
let tag = match tag.value {
Some(ref values) => values,
None => {
// in case the form validation fails, this will be tasked with rendering the page again with submitted values and display errors
let ids = pick_ids(db).await?;
println!("{:?}", &tag.context);
return Ok(Template::render(
"register",
context! {
ids,
previous: &tag.context,
},
)
.into());
}
};
println!("register: {:?}", tag);
fn normalize_opt(opt: &str) -> Option<&str> {
if opt.len() != 0 {
@ -136,21 +159,3 @@ pub async fn handle_register(mut db: DollTagsDb, tag: Form<TagForm<'_>>) -> Page
Ok(Redirect::to(uri!(public::show_profile(Some(tag.ident), microchip_id))).into())
}
#[post("/register", data = "<tag>", rank = 2)]
pub async fn handle_retry_register(
db: DollTagsDb,
tag: Form<Contextual<'_, TagForm<'_>>>,
) -> PageResult {
// in case the form validation fails, this will be tasked with rendering the page again with submitted values and display errors
let ids = pick_ids(db).await?;
Ok(Template::render(
"register",
context! {
ids,
previous: &tag.context,
},
)
.into())
}

View file

@ -1,7 +0,0 @@
{% macro pretty_pronouns(pronouns) %}
{% set fragments = pronouns | split(pat="/") %}
{% for fr in fragments %}
<span class="pronoun_fragment">{{fr}}</span>
{% if not loop.last %}/{% endif %}
{% endfor %}
{% endmacro pretty_pronouns %}

View file

@ -0,0 +1,7 @@
{% macro pretty_pronouns(pronouns) %}
{% set fragments = pronouns | split(pat="/") %}
{% for fr in fragments %}
<span class="pronoun_fragment">{{fr}}</span>
{% if not loop.last %}/{% endif %}
{% endfor %}
{% endmacro pretty_pronouns %}

View file

@ -0,0 +1,6 @@
{% macro value(ctx, name) %}
{% set values = ctx.values | get(key=name, default=[]) %}
{% if values | length > 0 %}
value="{{values | first}}"
{% endif %}
{% endmacro value %}

View file

@ -1,4 +1,5 @@
{% extends "base" %}
{% import "macros/form" as form %}
{% block title %}Register a new tag - {% endblock title %}
{% block main %}
<h2>Register a new tag</h2>
@ -16,6 +17,18 @@
<section>
<h3>Now, to the registration!</h3>
{% if previous.form_errors | length > 0 %}
<div class="form-error">
<h4>Some errors were encountered...</h4>
<ul>
{% for err in previous.form_errors %}
<li>{{err}}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<form method="POST">
<section>
<h4>Firstly, the tag's ID</h4>
@ -26,9 +39,9 @@
<div class="dual-fields bordered raised">
<div>
<p><label for="ident">Enter its ID</label></p>
<p class="heading"><label for="ident">Enter its ID</label></p>
<input type="text" inputmode="numeric" pattern="\d{6}" id="ident" name="ident" required size="6"
placeholder="000000" />
placeholder="000000" {{form::value(ctx=previous, name="ident" )}} />
<p>Or pick one of those pre-generated ones</p>
<div id="pregen_ids">
@ -38,9 +51,10 @@
</div>
</div>
<div>
<p><label for="microchip_id">If it's microchipped,<br />you may enter the chip's ID</label></p>
<p class="heading"><label for="microchip_id">If it's microchipped,<br />you may enter the chip's
ID</label></p>
<input type="text" pattern="(0x)?[a-fA-F0-9]+" id="microchip_id" name="microchip_id"
placeholder="A hexadecimal ID">
placeholder="A hexadecimal ID" {{form::value(ctx=previous, name="microchip_id" )}}>
</div>
</div>
</section>
@ -53,16 +67,17 @@
<label for="name">The entity's name and pronouns (required)</label>
<div class="dual-fields">
<div>
<input type="text" name="name" id="name" required placeholder="A name or callsign" />
<input type="text" name="name" id="name" required placeholder="A name or callsign"
{{form::value(ctx=previous, name="name" )}} />
<p class="note">Remember: names only mean what you want them to!</p>
</div>
<div>
<input class="pronoun" type="text" name="pronoun_subject" required maxlength="255"
placeholder="they" /> /
placeholder="they" {{form::value(ctx=previous, name="pronoun_subject" )}} /> /
<input class="pronoun" type="text" name="pronoun_object" required maxlength="255"
placeholder="them" /> /
placeholder="them" {{form::value(ctx=previous, name="pronoun_object" )}} /> /
<input class="pronoun" type="text" name="pronoun_possessive" required maxlength="255"
placeholder="theirs" />
placeholder="theirs" {{form::value(ctx=previous, name="pronoun_possessive" )}} />
</div>
</div>
</div>
@ -70,12 +85,14 @@
<label for="handler_name">The handler's name (required) and contact</label>
<div class="dual-fields">
<div>
<input type="text" name="handler_name" id="handler_name" required
placeholder="Another name or callsign" />
<input type="text" name="handler_name" id="handler_name"
placeholder="Another name or callsign" {{form::value(ctx=previous, name="handler_name"
)}} />
</div>
<div>
<input type="url" name="handler_link" id="handler_link"
placeholder="E-mails can be entered using mailto:" />
placeholder="E-mails can be entered using mailto:" {{form::value(ctx=previous,
name="handler_link" )}} />
<p class="note">Optional, will make the handler's name clickable.</p>
</div>
</div>
@ -95,21 +112,25 @@
<div class="fields">
<div>
<label for="kind">What kind of entity?</label>
<input type="text" name="kind" id="kind" placeholder="Something" />
<input type="text" name="kind" id="kind" placeholder="Something" {{form::value(ctx=previous,
name="kind" )}} />
</div>
<div>
<label for="breed">What breed is it?</label>
<input type="text" name="breed" id="breed" placeholder="Mutt :3" />
<input type="text" name="breed" id="breed" placeholder="Mutt :3" {{form::value(ctx=previous,
name="breed" )}} />
</div>
<div>
<label for="behaviour">Its general behaviour</label>
<input type="text" name="behaviour" id="behaviour" placeholder="Totally independent" />
<input type="text" name="behaviour" id="behaviour" placeholder="Totally independent"
{{form::value(ctx=previous, name="behaviour" )}} />
</div>
</div>
<div>
<label for="description">A description about it?</label>
<textarea name="description" id="description" rows="10"
placeholder="feel free to write a bit about it or not at all"></textarea>
placeholder="feel free to write a bit about it or not at all" {{form::value(ctx=previous,
name="description" )}}></textarea>
</div>
</div>
</div>
@ -126,15 +147,18 @@
<div class="dual-fields">
<div>
<label for="chassis_type">The chassis' type</label>
<input type="text" name="chassis_type" id="chassis_type" placeholder="Combat Doll" />
<input type="text" name="chassis_type" id="chassis_type" placeholder="Combat Doll"
{{form::value(ctx=previous, name="chassis_type" )}} />
</div>
<div>
<label for="chassis_id">Its assigned ID</label>
<input type="text" name="chassis_id" id="chassis_id" placeholder="E-249" />
<input type="text" name="chassis_id" id="chassis_id" placeholder="E-249"
{{form::value(ctx=previous, name="chassis_id" )}} />
</div>
<div>
<label for="chassis_color">Its dominant color</label>
<input type="text" name="chassis_color" id="chassis_color" placeholder="Grey" />
<input type="text" name="chassis_color" id="chassis_color" placeholder="Grey"
{{form::value(ctx=previous, name="chassis_color" )}} />
</div>
</div>
</div>

View file

@ -1,5 +1,5 @@
{% extends "base" %}
{% import "macros" as macros %}
{% import "macros/display" as macros %}
{% block title %}{{ profile.name }} - {% endblock title %}
{% block main %}