Display errors on invalid forms

It will probably need a bit of styling…
This commit is contained in:
Bat 2018-07-06 19:29:36 +02:00
parent 153400959c
commit 5f3afe900f
12 changed files with 68 additions and 39 deletions

2
Cargo.lock generated
View File

@ -999,6 +999,8 @@ dependencies = [
"rocket_csrf 0.1.0 (git+https://github.com/fdb-hiroshima/rocket_csrf?rev=80687a64a8b9d44e4983e63cca6d707498e92fc7)",
"rocket_i18n 0.1.1 (git+https://github.com/BaptisteGelez/rocket_i18n?rev=5b4225d5bed5769482dc926a7e6d6b79f1217be6)",
"rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"validator 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"validator_derive 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -10,6 +10,8 @@ failure = "0.1"
gettext-rs = "0.4"
heck = "0.3.0"
rpassword = "2.0"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
validator = "0.7"
validator_derive = "0.7"

View File

@ -15,6 +15,9 @@ extern crate rocket_contrib;
extern crate rocket_csrf;
extern crate rocket_i18n;
extern crate rpassword;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate validator;

View File

@ -41,7 +41,9 @@ fn activity_details(name: String, conn: DbConn) -> ActivityStream<CustomGroup> {
#[get("/blogs/new")]
fn new(user: User) -> Template {
Template::render("blogs/new", json!({
"account": user
"account": user,
"errors": null,
"form": null
}))
}
@ -50,7 +52,7 @@ fn new_auth() -> Flash<Redirect>{
utils::requires_login("You need to be logged in order to create a new blog", uri!(new))
}
#[derive(FromForm, Validate)]
#[derive(FromForm, Validate, Serialize)]
struct NewBlogForm {
#[validate(custom = "valid_slug")]
pub title: String
@ -98,7 +100,8 @@ fn create(conn: DbConn, data: LenientForm<NewBlogForm>, user: User) -> Result<Re
} else {
Err(Template::render("blogs/new", json!({
"account": user,
"errors": errors.inner()
"errors": errors.inner(),
"form": form
})))
}
}

View File

@ -77,12 +77,14 @@ fn new(blog: String, user: User, conn: DbConn) -> Template {
}))
} else {
Template::render("posts/new", json!({
"account": user
"account": user,
"errors": null,
"form": null
}))
}
}
#[derive(FromForm, Validate)]
#[derive(FromForm, Validate, Serialize)]
struct NewPostForm {
#[validate(custom = "valid_slug")]
pub title: String,
@ -113,7 +115,7 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
Err(e) => e
};
if let Err(e) = slug_taken_err {
errors.add("title", e)
errors.add("title", e);
}
if errors.is_empty() {
@ -150,7 +152,8 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
} else {
Err(Template::render("posts/new", json!({
"account": user,
"errors": errors.inner()
"errors": errors.inner(),
"form": form
})))
}
}

View File

@ -14,7 +14,9 @@ use plume_models::{
#[get("/login")]
fn new(user: Option<User>) -> Template {
Template::render("session/login", json!({
"account": user
"account": user,
"errors": null,
"form": null
}))
}
@ -27,7 +29,9 @@ struct Message {
fn new_message(user: Option<User>, message: Message) -> Template {
Template::render("session/login", json!({
"account": user,
"message": message.m
"message": message.m,
"errors": null,
"form": null
}))
}
@ -66,7 +70,8 @@ fn create(conn: DbConn, data: LenientForm<LoginForm>, flash: Option<FlashMessage
} else {
Err(Template::render("session/login", json!({
"account": user,
"errors": errors.inner()
"errors": errors.inner(),
"form": form
})))
}
}

View File

@ -121,7 +121,9 @@ fn activity_details(name: String, conn: DbConn) -> ActivityStream<CustomPerson>
#[get("/users/new")]
fn new(user: Option<User>) -> Template {
Template::render("users/new", json!({
"account": user
"account": user,
"errors": null,
"form": null
}))
}
@ -158,16 +160,16 @@ fn update(_name: String, conn: DbConn, user: User, data: LenientForm<UpdateUserF
Redirect::to(uri!(me))
}
#[derive(FromForm, Validate)]
#[derive(FromForm, Serialize, Validate)]
#[validate(schema(function = "passwords_match", skip_on_field_errors = "false"))]
struct NewUserForm {
#[validate(length(min = "1"))]
#[validate(length(min = "1", message = "Username can't be empty"))]
username: String,
#[validate(email)]
#[validate(email(message = "Invalid email"))]
email: String,
#[validate(length(min = "8"))]
#[validate(length(min = "8", message = "Password should be at least 8 characters long"))]
password: String,
#[validate(length(min = "8"))]
#[validate(length(min = "8", message = "Password should be at least 8 characters long"))]
password_confirmation: String
}
@ -196,7 +198,8 @@ fn create(conn: DbConn, data: LenientForm<NewUserForm>) -> Result<Redirect, Temp
Redirect::to(uri!(super::session::new))
})
.map_err(|e| Template::render("users/new", json!({
"errors": e.inner()
"errors": e.inner(),
"form": form
})))
}

View File

@ -1,4 +1,5 @@
{% extends "base" %}
{% import "macros" as macros %}
{% block title %}
{{ "New blog" | _ }}
@ -7,8 +8,8 @@
{% block content %}
<h1>{{ "Create a blog" | _ }}</h1>
<form method="post">
<label for="title">{{ "Title" | _ }}</label>
<input type="text" id="title" name="title" />
{{ macros::input(name="title", label="Title", errors=errors, form=form) }}
<input type="submit" value="{{ "Create blog" | _ }}"/>
</form>
{% endblock content %}

View File

@ -21,3 +21,12 @@
</p>
</div>
{% endmacro post_card %}
{% macro input(name, label, errors, form, type="text") %}
<label for="{{ name }}">{{ label | _ }}</label>
{% if errors is defined and errors[name] %}
{% for err in errors[name] %}
<p class="error">{{ err.message | _ }}</p>
{% endfor %}
{% endif %}
<input type="{{ type }}" id="{{ name }}" name="{{ name }}" value="{{ form[name] | default(value="") }}"/>
{% endmacro input %}

View File

@ -7,11 +7,18 @@
{% block content %}
<h1>{{ "Create a post" | _ }}</h1>
<form class="new-post" method="post">
<input type="text" class="title" name="title" placeholder="{{ "Title" | _ }}">
<textarea name="content" placeholder="{{ "Content" | _ }}"></textarea>
{{ macros::input(name="title", label="Title", errors=errors, form=form) }}
<label for="license">{{ "License" | _ }}</label>
<input type="text" id="licence" name="license" />
<label for="{{ name }}">{{ label | _ }}</label>
{% if errors is defined and errors.content %}
{% for err in errors.content %}
<p class="error">{{ err.message | _ }}</p>
{% endfor %}
{% endif %}
<textarea name="content" placeholder="{{ "Content" | _ }}" value="{{ form.content | default(value="") }}"></textarea>
{{ macros::input(name="license", label="License", errors=errors, form=form) }}
<input type="submit" value="{{ "Publish" | _ }}" />
</form>

View File

@ -10,11 +10,8 @@
<p>{{ message }}</p>
{% endif %}
<form method="post">
<label for="email_or_name">{{ "Username or email" | _ }}</label>
<input type="text" id="email_or_name" name="email_or_name" />
<label for="password">{{ "Password" | _ }}</label>
<input type="password" id="password" name="password" />
{{ macros::input(name="email_or_name", label="Username or email", errors=errors, form=form) }}
{{ macros::input(name="password", label="Password", errors=errors, form=form, type="password") }}
<input type="submit" value="{{ "Login" | _ }}" />
</form>

View File

@ -1,4 +1,5 @@
{% extends "base" %}
{% import "macros" as macros %}
{% block title %}
{{ "New Account" | _ }}
@ -7,17 +8,10 @@
{% block content %}
<h1>{{ "Create an account" | _ }}</h1>
<form method="post">
<label for="username">{{ "Username" | _ }}</label>
<input type="text" id="username" name="username" />
<label for="email">{{ "Email" | _ }}</label>
<input type="email" id="email" name="email" />
<label for="password">{{ "Password" | _ }}</label>
<input type="password" id="password" name="password" />
<label for="password_confirmation">{{ "Password confirmation" | _ }}</label>
<input type="password" id="password_confirmation" name="password_confirmation" />
{{ macros::input(name="username", label="Username", errors=errors, form=form) }}
{{ macros::input(name="email", label="Email", errors=errors, form=form, type="email") }}
{{ macros::input(name="password", label="Password", errors=errors, form=form, type="password") }}
{{ macros::input(name="password_confirmation", label="Password confirmation", errors=errors, form=form, type="password") }}
<input type="submit" value="{{ "Create account" | _ }}" />
</form>