### Define and Handle HTML Forms in Gleam Source: https://hexdocs.pm/formal/index Demonstrates defining a Gleam form schema for a `SignUp` type with email and password fields. It includes validation for email format, minimum password length, and password confirmation. The `handle_form_submission` function shows how to process incoming form data, decode it into the defined type, and handle success or error outcomes. ```gleam import formal/form // Define a type that is to be decoded from the form data pub type SignUp { SignUp(email: String, password: String) } /// A form that decodes the `Signup` value. fn signup_form() -> Form(Signup) { form.new({ use email <- form.field("email", { form.parse_email }) use password <- form.field("password", { form.parse_string |> form.check_string_length_more_than(7) }) use _ <- form.field("confirm", { form.parse_string |> form.check_confirms(password) }) SignUp(email: email, password: password) }) } // This function takes the list of key-value string pairs that a HTML form // produces. It then decodes the form data into a SignUp value, ensuring that // all the fields are present and valid. // pub fn handle_form_submission(values: List(#(String, String))) { let result = signup_form() |> form.add_values(values) |> form.run case result { Ok(data) -> { // Do something with the SignUp value here } Error(form) -> { // Re-render the form with the error messages } } } ``` -------------------------------- ### Gleam: new function to create a form Source: https://hexdocs.pm/formal/formal/form The `new` function creates a new form instance from a given schema. Users can add values using `add_*` functions and then execute the form with `run` to obtain the final value or any encountered errors. ```Gleam pub fn new(schema: Schema(model)) -> Form(model) ``` ```Gleam let schema = { use name <- form.field("name", { form.parse_string |> form.check_not_empty }) use name <- form.field("age", form.parse_int) form.success(Person(name:, age:)) } let form = form.new(schema) ``` -------------------------------- ### Run Form (Gleam) Source: https://hexdocs.pm/formal/formal/form Run a form, returning either the successfully parsed value if there are no errors, or a new instance of the form with the errors added to the fields. ```gleam pub fn run(form: Form(model)) -> Result(model, Form(model)) ``` -------------------------------- ### Parse URL (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser for URLs. Uses the `gleam/uri` module to parse and validate URLs. Returns a `MustBeUrl` error if the input cannot be parsed as a valid URI. ```gleam pub const parse_url: Parser(uri.Uri) ``` -------------------------------- ### Form Field Handling (Gleam) Source: https://hexdocs.pm/formal/formal/form Functions for managing form fields within the Formal library. `field` adds a parser for a named form field, `field_value` retrieves the first string value for a field, and `field_values` retrieves all string values for a field. ```gleam pub fn field( name: String, parser: Parser(value), continuation: fn(value) -> Schema(model), ) -> Schema(model) # Add a new parser to the form for a given form field name. ``` ```gleam pub fn field_value(form: Form(model), name: String) -> String # Get the first values for a given form field. let form = form |> form.add_int("one", 100) assert form.field_value(form, "one") == "100" assert form.field_value(form, "two") == "" ``` ```gleam pub fn field_values( form: Form(model), name: String, ) -> List(String) # Get all the values for a given form field. let form = form |> form.add_int("one", 100) |> form.add_string("one", "Hello") |> form.add_string("two", "Hi!") assert form.field_values(form, "one") == ["Hello", "100"] ``` -------------------------------- ### all_values Function - Gleam Source: https://hexdocs.pm/formal/formal/form Fetches all the key-value pairs currently stored within the form. This provides a comprehensive view of all data associated with the form. ```gleam pub fn all_values(form: Form(model)) -> List(#(String, String)) ``` -------------------------------- ### Gleam: parse function for custom input parsing Source: https://hexdocs.pm/formal/formal/form The `parse` function enables the creation of custom parsers for any data type. It requires a function that takes a list of strings and returns a `Result`. If parsing fails, it must provide a default 'zero' value and an error message string. ```Gleam pub fn parse( parser: fn(List(String)) -> Result(t, #(t, String)), ) -> Parser(t) ``` ```Gleam form.parse(fn(input) { case input { ["Squirtle", ..] -> Ok(Squirtle) ["Bulbasaur", ..] -> Ok(Bulbasaur) ["Charmander", ..] -> Ok(Charmander) _ -> Error(#(Squirtle, "must be a starter Pokémon")) } }) ``` -------------------------------- ### Parse Optional (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser that applies another parser if there is a non-empty-string input value for the field. ```gleam pub fn parse_optional( parser: Parser(output), ) -> Parser(option.Option(output)) ``` -------------------------------- ### Parse Float (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser for floating point numbers. Returns a `MustBeFloat` error if the input cannot be parsed as a float. ```gleam pub const parse_float: Parser(Float) ``` -------------------------------- ### Parse String (Gleam) Source: https://hexdocs.pm/formal/formal/form Parse a string value. This parser can never fail. ```gleam pub const parse_string: Parser(String) ``` -------------------------------- ### Gleam: map function for data transformation Source: https://hexdocs.pm/formal/formal/form The `map` function transforms the parsed value of a parser, similar to `list.map` or `result.map`. It takes a parser and a mapper function, returning a new parser that applies the mapper to the successfully parsed value. ```Gleam pub fn map( parser: Parser(t1), mapper: fn(t1) -> t2, ) -> Parser(t2) ``` -------------------------------- ### Parse Time (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser for time values. Parses times in HH:MM:SS or HH:MM format and returns a `calendar.TimeOfDay` value. Returns a `MustBeTime` error if the input cannot be parsed as a valid time. ```gleam pub const parse_time: Parser(calendar.TimeOfDay) ``` -------------------------------- ### Error Translation Functions (Gleam) Source: https://hexdocs.pm/formal/formal/form Functions to translate `FieldError` types into user-friendly strings. `en_gb` provides British English translations, while `en_us` provides American English translations, notably for the word 'color'. ```gleam pub fn en_gb(error: FieldError) -> String # Translates `FieldError`s into strings suitable for showing to the user. assert en_us(MustBeColour) == "must be a hex colour code" ``` ```gleam pub fn en_us(error: FieldError) -> String # Translates `FieldError`s into strings suitable for showing to the user. # The same as `en_gb`, but with Americanised spelling of the word “color”. assert en_us(MustBeColour) == "must be a hex color code" ``` -------------------------------- ### Parse List (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser that applies another parser to each input value in a list. Takes a parser for a single value and returns a parser that can handle multiple values of the same type. This is useful for form fields that can have multiple values, such as checkboxes, multi-selects, or just repeated inputs of other types. ```gleam pub fn parse_list(parser: Parser(output)) -> Parser(List(output)) ``` -------------------------------- ### Gleam: parse_checkbox parser for boolean input Source: https://hexdocs.pm/formal/formal/form The `parse_checkbox` is a parser for boolean values from checkbox inputs. An absent value is `False`, while any present value (including an empty string or 'on') is `True`. This is useful for handling user agreements or options. ```Gleam pub const parse_checkbox: Parser(Bool) ``` ```Gleam let schema = { use agreed <- form.field("terms-and-conditions", { form.parse_checkbox |> form.check_accepted }) form.success(Signup(agreed:)) } ``` -------------------------------- ### Parse Int (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser for a whole number. Returns a `MustBeInt` error if the input cannot be parsed as a valid int. ```gleam pub const parse_int: Parser(Int) ``` -------------------------------- ### Gleam: language function for form translation Source: https://hexdocs.pm/formal/formal/form The `language` function in the Formal library allows supplying a translation function for `FieldError`s. This function converts errors into user-friendly text. It supports built-in languages like `en_gb` and `en_us`, defaulting to `en_gb` if no language is specified. ```Gleam pub fn language( form: Form(model), translator: fn(FieldError) -> String, ) -> Form(model) ``` -------------------------------- ### formal/form: Form Type Source: https://hexdocs.pm/formal/formal/form An opaque type representing a form, created from a Schema using the 'new' function. It is used for supplying values via 'add_*' functions and processing with 'run'. ```APIDOC Form(model): opaque A form! Created from a `Schema` with the `new` function. Supply values to a form with the `add_*` functions and then pass it to the `run` function to get either the resulting value or any errors. Use the `language` function to supply a new translation function to change the language of the error messages returned by the `field_error_text` function. The default language is `en_gb` English. ``` -------------------------------- ### Check Integer Less Than Limit (Gleam) Source: https://hexdocs.pm/formal/formal/form Ensures that an integer value parsed by a `Parser` is less than a specified limit. This is useful for validating input ranges. ```gleam pub fn check_int_less_than( parser: Parser(Int), limit: Int, ) -> Parser(Int) ``` ```gleam let schema = { use age <- form.field("age", { form.parse_int |> form.check_int_less_than(150) }) form.success(Person(age:)) } ``` -------------------------------- ### add_values Function - Gleam Source: https://hexdocs.pm/formal/formal/form Adds multiple key-value pairs to a form. This function is ideal for populating a form with data originating from sources like HTTP request form bodies or HTML form submissions. ```gleam pub fn add_values( form: Form(a), values: List(#(String, String)), ) -> Form(a) ``` ```gleam use formdata <- wisp.require_form(request) let form <- new_user_form() |> form.add_values(formdata.values) ``` -------------------------------- ### formal/form: FieldError Type and Constructors Source: https://hexdocs.pm/formal/formal/form Defines the possible errors that can occur during form validation. Includes specific error types like MustBeInt, MustBeEmail, and length/range checks, as well as a CustomError option. ```APIDOC FieldError: MustBePresent MustBeInt MustBeFloat MustBeEmail MustBePhoneNumber MustBeUrl MustBeDate MustBeTime MustBeDateTime MustBeColour MustBeStringLengthMoreThan(limit: Int) MustBeStringLengthLessThan(limit: Int) MustBeIntMoreThan(limit: Int) MustBeIntLessThan(limit: Int) MustBeFloatMoreThan(limit: Float) MustBeFloatLessThan(limit: Float) MustBeAccepted MustConfirm For confirmation of passwords, etc. Must match the first field. MustBeUnique For values that must be unique. e.g. user email addresses. CustomError(message: String) ``` -------------------------------- ### Parse Email (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser that validates email addresses. Performs basic email validation by checking for the presence of an “@” symbol. Returns a `MustBeEmail` error if the input is not a valid email format. ```gleam pub const parse_email: Parser(String) ``` -------------------------------- ### formal/form: Schema Type Source: https://hexdocs.pm/formal/formal/form An opaque type representing a schema, which is a description of how to decode typed data from form data. Schemas are used to create new form objects via the 'new' function. ```APIDOC Schema(model): opaque A description of how to decode from typed value from form data. This can be used to create a new form object using the `new` function. ``` -------------------------------- ### Gleam: parse_colour parser for hex color strings Source: https://hexdocs.pm/formal/formal/form The `parse_colour` parser accepts color values in HTML hex format (e.g., '#FF0000'). It returns the hex color string upon successful parsing. Invalid formats will result in a `MustBeColour` error. ```Gleam pub const parse_colour: Parser(String) ``` ```Gleam let schema = { use background_color <- form.field("background_color", form.parse_colour) form.success(Theme(background_color:)) } ``` -------------------------------- ### Check String Length Less Than Limit (Gleam) Source: https://hexdocs.pm/formal/formal/form Ensures that a string value parsed by a `Parser` has a length less than a specified limit. Useful for input field constraints. ```gleam pub fn check_string_length_less_than( parser: Parser(String), limit: Int, ) -> Parser(String) ``` ```gleam let schema = { use username <- form.field("username", { form.parse_string |> form.check_string_length_less_than(20) }) form.success(User(username:)) } ``` -------------------------------- ### Check Integer More Than Limit (Gleam) Source: https://hexdocs.pm/formal/formal/form Ensures that an integer value parsed by a `Parser` is more than a specified limit. This is useful for validating input ranges. ```gleam pub fn check_int_more_than( parser: Parser(Int), limit: Int, ) -> Parser(Int) ``` ```gleam let schema = { use age <- form.field("age", { form.parse_int |> form.check_int_more_than(0) }) form.success(Person(age:)) } ``` -------------------------------- ### Check String Not Empty (Gleam) Source: https://hexdocs.pm/formal/formal/form Ensures that a string value parsed by a `Parser` is not an empty string. This is commonly used for required text fields. ```gleam pub fn check_not_empty(parser: Parser(String)) -> Parser(String) ``` ```gleam let schema = { use tags <- form.field("tag", { form.parse_string |> form.check_not_empty }) form.success(Article(tags:)) } ``` -------------------------------- ### Parse Phone Number (Gleam) Source: https://hexdocs.pm/formal/formal/form A parser for phone numbers. Phone numbers are checked with rules for length, digits, and optional leading '+', allowing '-', ' ', '(', and ')' characters which are removed. Returns a `MustBePhoneNumber` error if the input doesn’t satisfy these rules. ```gleam pub const parse_phone_number: Parser(String) ``` -------------------------------- ### Gleam: parse_date_time parser for datetime values Source: https://hexdocs.pm/formal/formal/form The `parse_date_time` parser handles datetime strings in the HTML 'datetime-local' format (e.g., '2023-12-25T14:30'). It returns a tuple containing `calendar.Date` and `calendar.TimeOfDay`. Invalid formats will trigger a `MustBeDateTime` error. ```Gleam pub const parse_date_time: Parser( #(calendar.Date, calendar.TimeOfDay), ) ``` ```Gleam let schema = { use created_at <- form.field("created_at", form.parse_date_time) form.success(Event(created_at:)) } ``` -------------------------------- ### Gleam: parse_date parser for YYYY-MM-DD dates Source: https://hexdocs.pm/formal/formal/form The `parse_date` parser is designed to parse dates in the 'YYYY-MM-DD' format. It returns a `calendar.Date` value. If the input string does not conform to this format, a `MustBeDate` error is returned. ```Gleam pub const parse_date: Parser(calendar.Date) ``` ```Gleam let schema = { use birth_date <- form.field("birth_date", form.parse_date) form.success(Person(birth_date:)) } ``` -------------------------------- ### Check String Length More Than Limit (Gleam) Source: https://hexdocs.pm/formal/formal/form Ensures that a string value parsed by a `Parser` has a length more than a specified limit. Useful for input field constraints like password length. ```gleam pub fn check_string_length_more_than( parser: Parser(String), limit: Int, ) -> Parser(String) ``` ```gleam let schema = { use password <- form.field("password", { form.parse_string |> form.check_string_length_more_than(8) }) form.success(User(password:)) } ``` -------------------------------- ### all_errors Function - Gleam Source: https://hexdocs.pm/formal/formal/form Retrieves all errors present within a form. If no validation has been run or errors added via `add_error`, this function will return an empty list. ```gleam pub fn all_errors( form: Form(model), ) -> List(#(String, List(FieldError))) ``` -------------------------------- ### Form Error Retrieval (Gleam) Source: https://hexdocs.pm/formal/formal/form Functions to inspect errors associated with a form. `field_error_messages` retrieves a list of user-friendly error messages for a specific field, using the configured translator. `field_errors` retrieves the raw `FieldError` types for a field. ```gleam pub fn field_error_messages( form: Form(model), name: String, ) -> List(String) # Get the error messages for a field, if there are any. # The text is formatted using the translater function given with the # `langauge` function. The default translater is `en_gb`. ``` ```gleam pub fn field_errors( form: Form(model), name: String, ) -> List(FieldError) # Get all the form. # If the `run` function or the `add_error` function have not been called then # the form is clean and won’t have any errors yet. ``` -------------------------------- ### Set Form Values in Gleam Source: https://hexdocs.pm/formal/formal/form Replaces any existing values of a form with new values. This function is useful for adding values from a HTTP request form body sent to your server, or from a HTML form element in your browser-based application. ```gleam pub fn set_values( form: Form(a), values: List(#(String, String)), ) -> Form(a) ``` ```gleam use formdata <- wisp.require_form(request) let form <- new_user_form() |> form.set_values(formdata.values) ``` -------------------------------- ### check_accepted Function - Gleam Source: https://hexdocs.pm/formal/formal/form Ensures that a boolean value parsed by the parser is `True`. This is commonly used for checkboxes that must be explicitly accepted, like terms and conditions. ```gleam pub fn check_accepted(parser: Parser(Bool)) -> Parser(Bool) ``` ```gleam let schema = { use discount <- form.field("terms-and-conditions", { form.parse_checkbox |> form.check_accepted }) form.success(Product(discount:)) } ``` -------------------------------- ### formal/form: Parser Type and Usage Source: https://hexdocs.pm/formal/formal/form An opaque type representing a parser, used to extract a value from form data, convert it to a desired type, and optionally validate it. Parsers are used with the 'field' function and exhibit short-circuiting behavior. ```APIDOC Parser(value): opaque A parser extracts a value from from values, converting it to a desired type and optionally validating the value. Parsers are used with the `field` function. See the `parse_*` and `check_*` functions for more information. Functions that start with `parse_*` are *short-circuiting*, so any parser functions that come afterwrads will not be run. For example, given this code: ```gleam form.parse_int |> form.check_int_more_than(0) ``` If the input is not an int then `parse_int` will fail, causing `check_int_more_than` not to run, so the errors will be `[MustBeInt]`. ``` -------------------------------- ### check Function - Gleam Source: https://hexdocs.pm/formal/formal/form Applies a custom validation check to a parser. This allows for complex validation rules beyond basic type parsing, returning either the validated value or a string error message. ```gleam pub fn check( parser: Parser(b), checker: fn(b) -> Result(b, String), ) -> Parser(b) ``` ```gleam let must_not_be_rude = fn(text) { case contains_swear_word(text) { True -> Error("must not be rude") False -> Ok(text) } } let schema = { use name <- form.field("name", { form.parse_string |> form.check(must_not_be_rude) }) form.success(Profile(name:)) } ``` -------------------------------- ### check_float_less_than Function - Gleam Source: https://hexdocs.pm/formal/formal/form Validates that a float value is strictly less than a specified limit. This is useful for setting upper bounds on numerical inputs. ```gleam pub fn check_float_less_than( parser: Parser(Float), limit: Float, ) -> Parser(Float) ``` ```gleam let schema = { use discount <- form.field("discount", { form.parse_float |> form.check_float_less_than(100.0) }) form.success(Product(discount:)) } ``` -------------------------------- ### add_string Function - Gleam Source: https://hexdocs.pm/formal/formal/form Adds a string value to a designated field within the form. This is commonly used to pre-populate form fields with data that the user can then modify. ```gleam pub fn add_string( form: Form(model), field: String, value: String, ) -> Form(model) ``` -------------------------------- ### check_float_more_than Function - Gleam Source: https://hexdocs.pm/formal/formal/form Ensures that a float value is strictly greater than a specified limit. This is commonly used to enforce minimum values for numerical inputs. ```gleam pub fn check_float_more_than( parser: Parser(Float), limit: Float, ) -> Parser(Float) ``` ```gleam let schema = { use price <- form.field("price", { form.parse_float |> form.check_float_more_than(0.0) }) form.success(Product(price:)) } ``` -------------------------------- ### check_confirms Function - Gleam Source: https://hexdocs.pm/formal/formal/form Validates that a field's value matches another specified value. This is frequently used for password confirmation fields to ensure consistency. ```gleam pub fn check_confirms(parser: Parser(t), other: t) -> Parser(t) ``` ```gleam let schema = { use password <- form.field("password-confirmation", { form.parse_string |> form.check_string_length_more_than(8) }) use _ <- form.field("password-confirmation", { form.parse_string |> form.check_confirms(password) }) form.success(User(password:)) } ``` -------------------------------- ### Finalize Parser in Gleam Source: https://hexdocs.pm/formal/formal/form Finalises a parser, having successfully parsed a value. This function is used to mark the successful completion of a parsing operation. ```gleam pub fn success(value: model) -> Schema(model) ``` -------------------------------- ### add_int Function - Gleam Source: https://hexdocs.pm/formal/formal/form Adds an integer value to a specified field in the form. This function is particularly helpful for pre-filling form fields with existing data, allowing users to edit previously saved values. ```gleam pub fn add_int( form: Form(model), field: String, value: Int, ) -> Form(model) ``` -------------------------------- ### add_error Function - Gleam Source: https://hexdocs.pm/formal/formal/form Adds a specific error to a field within a form. This is useful for integrating custom validation logic that runs outside the standard form schema, allowing error messages to be displayed to the user through the form interface. ```gleam pub fn add_error( form: Form(model), name: String, error: FieldError, ) -> Form(model) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.