Browsers have support for client side validation of form data built in. We can use this along with server side validation to give the user a nice experience and ensure security on the back end.
In the following form we use an email type and a required attribute. The browser will now block form submission until the field is filled in with a valid email address and password.
Email:
Submit
We can write this same form using Dioxus. Update crates/ui-components/src/users.rs
with a form to add users.
use crate Layout;
use User;
use *;
use component;
use avatar_svg;
// Define the properties for IndexPage
// Add Clone and PartialEq here
// Define the IndexPage component
Note: for
and type
are Rust keywords. We must prefix them with r#
so Rust knows that we want the raw string literal of "for" and "type".
We need to install serde to transform the HTTP body into a Rust struct.
Axum has support for Handlers. We can use those in a lot of different ways and one way is for form implementations. We are going to create a create_form
handler to save new users to our database.
Create a new file crates/web-server/src/new_user.rs
use Deserialize;
use crate CustomError;
use ;
// 👇 create new SignUp struct
// 👇 handle form submission
pub async
In crates/web-server/main.rs
add a the new module to the top of the file:
Add post
to our use
section.
use ;
And add another route like the following to the list of routes to catch the post of the form so that the Router now looks like:
// build our application with a route
let app = new
.route
.route
.route
.layer
.layer;
In crates/web-server/Cargo.toml
we also need to update the Axum dependency to add the form feature:
axum =
The compiler will complain because we haven't added the database code to handle form submission.
We are using db::queries::users::create_user()
in our accept_form
handler. We must also update crates/db/queries/users.sql
to include our actual SQL query
--: User()
--! get_users : User
SELECT
id,
email
FROM users;
-- 👇 add `create_user` query
--! create_user
INSERT INTO
users (email)
VALUES
(:email);
You should get results like the screenshot below.
If you add an email to the form and press submit, the server should handle that request and update the users table.
Our web form validates that the user input is an email. We should also check that the user input is an email on the server. We can use Validator which will allow us to add validation to the SignUp
struct.
Install the Validator
crate.
Update crates/web-server/src/new_user.rs
and add validation.
use Deserialize;
use Validate;
use crate CustomError;
use ;
// 👇 handle form submission
pub async
And we can test that our validation works by sending a request directly to the server (bypassing the browser form):