formal/form
Types
An invalid or unfinished form. This is either created by the new
function, which creates a new empty form, or by the finish
function when
the validation failed, returning the invalid form.
pub type FormState {
FormState(
values: Dict(String, List(String)),
errors: Dict(String, String),
)
}
Constructors
-
FormState( values: Dict(String, List(String)), errors: Dict(String, String), )
A collection of validations that decode data from a form into a typed value.
See the module documentation for an overview of how to use this type to validate a form.
pub opaque type FormValidator(output)
Functions
pub fn and(
previous: fn(a) -> Result(b, String),
next: fn(b) -> Result(c, String),
) -> fn(a) -> Result(c, String)
Add an additional validation step to the field decoder function.
This function behaves similar to the try
function in the standard library
gleam/result
module.
pub fn bool(input: String) -> Result(Bool, String)
Decode the field value as a bool.
The input value must be “on” to be considered true as this is the value that HTML checkboxes use when checked.
Examples
bool("on")
# -> Ok(True)
bool("true")
# -> Ok(False)
bool("")
# -> Ok(False)
pub fn decoding(
into constructor: fn(a) -> b,
) -> FormValidator(fn(a) -> b)
Set the constructor that is used to create the success value if the form decodes and validates successfully.
You will want to use a curried constructor function here. The curry*
functions in the gleam/function
standard library module can be used to
help with this.
pub fn field(
form: FormValidator(fn(a) -> b),
name: String,
decoder: fn(String) -> Result(a, String),
) -> FormValidator(b)
Add the next field to be decoded and validated from the form, corresponding to the next argument to the constructor.
pub fn finish(form: FormValidator(a)) -> Result(a, FormState)
Finish the form validation, returning the success value built using the constructor, or the invalid form containing the values and errors, which can be used to render the form again to the user.
pub fn float(input: String) -> Result(Float, String)
Decode the field value as a float.
The input value must have a decimal point.
Examples
float("12.34")
# -> Ok(123)
float("1")
# -> Error("Must be a number with a decimal point")
float("ok")
# -> Error("Must be a number with a decimal point")
pub fn int(input: String) -> Result(Int, String)
Decode the field value as an int.
Examples
int("123")
# -> Ok(123)
int("ok")
# -> Error("Must be a whole number")
pub fn list(
of decoder: fn(String) -> Result(a, String),
) -> fn(List(String)) -> Result(List(a), String)
Decode all the values for a field as a given type. This is useful with the
multifield
function when there are multiple inputs with the same name in
the form.
Examples
int("123")
# -> Ok(123)
int("ok")
# -> Error("Must be a whole number")
pub fn message(
result: fn(a) -> Result(b, String),
message: String,
) -> fn(a) -> Result(b, String)
Set a custom error message for a field decoder, overwriting the previous error message if there is one at this point in the decoder, doing nothing if the decoder is successful.
pub fn multifield(
form: FormValidator(fn(a) -> b),
name: String,
decoder: fn(List(String)) -> Result(a, String),
) -> FormValidator(b)
Add the next field to be decoded and validated from the form, corresponding to the next argument to the constructor.
This function is useful when you have multiple inputs with the same name in
the form, and you most likely want to use it with the list
decoder
function. When there is only a single input with the given name in the form
then the field
function is more appropriate.
pub fn must_be_accepted(input: Bool) -> Result(Bool, String)
Assert that the bool input is true. This is expected to be used with checkboxes and has an error message that reflects that.
Examples
must_be_accepted(True)
# -> Ok(True)
must_be_accepted(False)
# -> Error("Must be accepted")
pub fn must_be_an_email(input: String) -> Result(String, String)
Assert that the string input looks like an email address.
It could still be an invalid email address even if it looks like one. To validate an email address is valid you will need to send an email to it and ensure your user receives it.
Examples
must_be_an_email("hello@example.com")
# -> Ok("hello@example.com")
must_be_an_email("Something")
# -> Error("Must be an email")
pub fn must_be_greater_float_than(
minimum: Float,
) -> fn(Float) -> Result(Float, String)
Assert that the float input is greater than the given minimum.
It could still be an invalid email address even if it looks like one. To validate an email address is valid you will need to send an email to it and ensure your user receives it.
Examples
let check = must_be_greater_float_than(3.3)
check(4.1)
# -> Ok(3.3)
let check = must_be_greater_float_than(3.3)
check(2.0)
# -> Error("Must be greater than 3.3")
pub fn must_be_greater_int_than(
minimum: Int,
) -> fn(Int) -> Result(Int, String)
Assert that the int input is greater than the given minimum.
It could still be an invalid email address even if it looks like one. To validate an email address is valid you will need to send an email to it and ensure your user receives it.
Examples
let check = must_be_greater_int_than(10)
check(12)
# -> Ok(12)
let check = must_be_greater_int_than(10)
check(2)
# -> Error("Must be greater than 10")
pub fn must_be_lesser_float_than(
maximum: Float,
) -> fn(Float) -> Result(Float, String)
Assert that the float input is greater than the given minimum.
It could still be an invalid email address even if it looks like one. To validate an email address is valid you will need to send an email to it and ensure your user receives it.
Examples
let check = must_be_lesser_float_than(10)
check(12)
# -> Ok(12)
let check = must_be_lesser_float_than(10)
check(2)
# -> Error("Must be less than 10")
pub fn must_be_lesser_int_than(
maximum: Int,
) -> fn(Int) -> Result(Int, String)
Assert that the int input is greater than the given minimum.
It could still be an invalid email address even if it looks like one. To validate an email address is valid you will need to send an email to it and ensure your user receives it.
Examples
let check = must_be_lesser_int_than(10)
check(12)
# -> Ok(12)
let check = must_be_lesser_int_than(10)
check(2)
# -> Error("Must be less than 10")
pub fn must_be_string_longer_than(
length: Int,
) -> fn(String) -> Result(String, String)
Assert that the string has at least the given length.
Examples
let check = must_be_string_longer_than(4)
check("hello")
# -> Ok("hello")
let check = must_be_string_longer_than(4)
check("hi")
# -> Error("Must be longer than 2 characters")
pub fn must_equal(
expected: a,
because error_message: String,
) -> fn(a) -> Result(a, String)
Assert that the bool input is true. This is expected to be used with checkboxes and has an error message that reflects that.
Examples
let check = must_equal(42, "Must be the answer to everything")
check(42)
# -> Ok(42)
let check = must_equal(42, "Must be the answer to everything")
check(2)
# -> Error("Must be the answer to everything")
pub fn must_not_be_empty(input: String) -> Result(String, String)
Assert that the string input must not be empty, returning an error if it is.
Examples
must_not_be_empty("Hello")
# -> Ok("Hello")
must_not_be_empty("")
# -> Error("Must not be blank")
pub fn new() -> FormState
Create a new empty form.
You likely want to use this when rendering a page containing a new form.
pub fn number(input: String) -> Result(Float, String)
Decode the field value as a float.
The decimal point is optional.
Examples
number("12.34")
# -> Ok(123)
number("1")
# -> Ok(1.0)
number("ok")
# -> Error("Must be a number")
pub fn parameter(f: fn(a) -> b) -> fn(a) -> b
This function is used to create constructor functions that take arguments
one at a time, making them suitable for passing to the decode
function.
Examples
decoding({
use name <- parameter
use email <- parameter
})
|> with_values(values)
|> field("email", string)
|> field("password", string)
|> finish
pub fn string(input: String) -> Result(String, String)
Decode the field value as a string.
Examples
string("hello")
# -> Ok("hello")
pub fn with_values(
form: FormValidator(a),
values: List(#(String, String)),
) -> FormValidator(a)
Set the values from the form submission to be validated.
HTML forms can have multiple fields with the same name. This function will
use the final value with each name, so if you wish to use a different value
consider removing the duplicates or using with_values_dict
.
pub fn with_values_dict(
form: FormValidator(a),
values: Dict(String, List(String)),
) -> FormValidator(a)
Set the values from the form submission to be validated.