ozmat / elm-forms / Forms.Validation

This module provides the validation logic for the library. Please refer to the examples for a better understanding

Field Validation


type alias FieldValidation err a =
Internal.FieldValidation err a

A FieldValidation represents the validation of a Field.

It can be a success or a failure (and sometimes a configFailure, please refer to the ConfigError definition and the README troubleshooting section).

You are not going to use the FieldValidation itself but you will create a FieldValidation function that will help you validate Field

success : a -> FieldValidation err a

Returns a successful FieldValidation using a result

failure : err -> FieldValidation err a

Returns a failed FieldValidation using an error

configFailure : Result.ConfigError -> FieldValidation err a

Returns a failed FieldValidation using a ConfigError

Field Type

First of all you need to specify what type of Field you want to validate

stringField : (String -> FieldValidation err a) -> Forms.Value.Internal.Value -> FieldValidation err a

Helps validating a string Field (input, select). By using this function you basically say "this field is an input or a select, we are waiting for a string here". And then you pass your string FieldValidation function that will validate the string

type YourError
    = EmptyString

notEmpty : Value -> FieldValidation YourError String
notEmpty =
    stringField
        (\aString ->
            if String.isEmpty aString then
                failure EmptyString

            else
                success aString
        )

Note: if the field Value is not a string, it fails with a WrongType ConfigError

boolField : (Basics.Bool -> FieldValidation err a) -> Forms.Value.Internal.Value -> FieldValidation err a

Helps validating a bool Field (checkbox). By using this function you basically say "this field is a checkbox, we are waiting for a bool here". And then you pass your bool FieldValidation function that will validate the bool

type YourError
    = NotChecked

isChecked : Value -> FieldValidation YourError Bool
isChecked =
    checkboxField
        (\aBool ->
            if aBool then
                success aBool

            else
                failure NotChecked
        )

Note: if the field Value is not a bool, it fails with a WrongType ConfigError

Basic Validation

Then you create a validation function for this specific type, or use the basic validation helpers defined below.

validation : err -> (a -> Basics.Bool) -> a -> FieldValidation err a

Helps creating a basic validation function. It is useful when you have a basic test and you only need to fail with one error.

type YourError
    = MustBeEmpty

emptyValidation : String -> FieldValidation YourError String
emptyValidation =
    validation MustBeEmpty String.isEmpty

isChecked : err -> (Basics.Bool -> FieldValidation err a) -> Basics.Bool -> FieldValidation err a

Helps validating a Bool that is True (checkbox checked). If the Bool is False, fails with the given error.

type YourError
    = NotChecked
    | ...

postValidation : Bool -> FieldValidation YourError a
...

validateField : Bool -> FieldValidation YourError a
validateField =
    isChecked NotChecked postValidation

int : err -> (Basics.Int -> FieldValidation err a) -> String -> FieldValidation err a

Helps validating a String that can be cast into an Int. If the String cannot be cast, fails with the given error.

type YourError
    = NotInt
    | ...

postValidation : Int -> FieldValidation YourError a
...

validateField : String -> FieldValidation YourError a
validateField =
    int NotInt postValidation

float : err -> (Basics.Float -> FieldValidation err a) -> String -> FieldValidation err a

Helps validating a String that can be cast into a Float. If the String cannot be cast, fails with the given error.

type YourError
    = NotFloat
    | ...

postValidation : Float -> FieldValidation YourError a
...

validateField : String -> FieldValidation YourError a
validateField =
    float NotFloat postValidation

notEmpty : err -> (String -> FieldValidation err a) -> String -> FieldValidation err a

Helps validating a String that is not empty. If the String is empty, fails with the given error.

type YourError
    = StringEmpty
    | ...

postValidation : String -> FieldValidation YourError a
...

validateField : String -> FieldValidation YourError a
validateField =
    notEmpty StringEmpty postValidation

length : Basics.Int -> Basics.Int -> err -> (String -> FieldValidation err a) -> String -> FieldValidation err a

Helps validating a String that has a specific length (> low && < high). If the String has a different length, fails with the given error.

type YourError
    = WrongLength
    | ...

postValidation : String -> FieldValidation YourError a
...

validateField : String -> FieldValidation YourError a
validateField =
    length 4 6 WrongLength postValidation

email : err -> (String -> FieldValidation err a) -> String -> FieldValidation err a

Helps validating a String that is an email. If the Stringis not an email, fails with the given error.

type YourError
    = NotValidEmail
    | ...

postValidation : String -> FieldValidation YourError a
...

validateField : String -> FieldValidation YourError a
validateField =
    email NotValidEmail postValidation

passwordMatch : err -> (String -> FieldValidation err a) -> Forms.Value.Internal.Value -> Forms.Value.Internal.Value -> FieldValidation err a

Helps validating two string Value that match. If the strings don't match, fails with the given error.

type YourError
    = DifferentPassword
    | ...

postValidation : String -> FieldValidation YourError a
...

validateField : Value -> Value -> FieldValidation YourError a
validateField =
    passwordMatch DifferentPassword postValidation

Note: if the two Value are not strings, it fails with a WrongType ConfigError

Form Validation


type alias FormValidation comparable err a =
Internal.FormValidation comparable err a

A FormValidation represents the validation of a Form.

It is similar to FieldValidation: you are not going use the type itself but instead you will create a Validate function (see below)

valid : a -> FormValidation comparable err a

Returns a successful FormValidation using a result

Validate


type alias Validate comparable err a =
Internal.Validate comparable err a

Validate represents the function that validates a Form.

It takes Fields and creates a FormValidation.

It usually starts with the valid function, representing the final result, and then uses the different Validate helpers to validate each form Field

validateForm : Validate String YourError Model
validateForm fields =
    valid Model
        |> required fields "field-name1" (stringField ...)
        |> required fields "field-name2" (boolField ...)
        |> optional fields "field-name3" ...
        ...

required : Forms.Field.Internal.Fields comparable -> comparable -> (Forms.Value.Internal.Value -> FieldValidation err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates a required Field. This is the basic use case : the Field is required and you want to validate it.

...
    |> required fields "first-name" (stringField <| someStringValidation)
    ...

hardcoded : a -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Hardcodes a value. This is useful when you need to harcode a specific value during the validation process

...
    |> hardcoded "someHarcodedValue"
    ...

optional : Forms.Field.Internal.Fields comparable -> comparable -> a -> (String -> FieldValidation err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates an optional Field. This will use the validation function if the Field is not empty or use the default value otherwise

...
    |> optional fields "wallet" 0.0 (float ...)
    ...

Note: it only works on string Field so no need to use stringField here

optionalWithMaybe : Forms.Field.Internal.Fields comparable -> comparable -> (String -> FieldValidation err a) -> FormValidation comparable err (Maybe a -> b) -> FormValidation comparable err b

Validates an optional Field with Maybe. Same logic than optional but the default value is Nothing and the validated one is Just

...
    |> optionalWithMaybe fields "age" (int ...)
    ...

Note: it only works on string Field so no need to use stringField here

discardable : Forms.Field.Internal.Fields comparable -> comparable -> (Forms.Value.Internal.Value -> FieldValidation err a) -> FormValidation comparable err b -> FormValidation comparable err b

Validates a discardable Field. This is useful when you need to validate the Field but don't need the result.

...
    |> discardable fields "terms" (boolField <| isChecked ...)
    ...

twoFields : Forms.Field.Internal.Fields comparable -> comparable -> comparable -> (Forms.Value.Internal.Value -> Forms.Value.Internal.Value -> FieldValidation err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates two Field together. This is useful when you need to validate one Field that depends on another, but you only need to store one result.

...
    |> FV.twoFields fields "password" "password-repeat" (passwordMatch ...)
    ...

Note : the validation function takes two field Value so you cannot use the stringField and boolField helpers here, you will have to deal with Value

fieldgroup : Forms.Field.Internal.Fields comparable -> comparable -> (Forms.Field.Internal.Fields comparable -> FormValidation comparable err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates a fieldgroup. This is mainly useful when you need to nest another validation process

 ...
    |> fieldgroup fields "job-profile" jobProfileValidate
    ...

Non-accumulative

The default behavior of Validate is to validate each Field and gather all the errors while validating the all Form (it is accumulative).

But if you need a non-accumulative validation process (this means that the validation stops at the first error encountered) there are non-accumulative versions of the validate helpers.

They have the same name but finish with a 1. Do not mix them with the default ones.

required1 : Forms.Field.Internal.Fields comparable -> comparable -> (Forms.Value.Internal.Value -> FieldValidation err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates a required Field (non-accumulative)

hardcoded1 : a -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Hardcodes a value (non-accumulative)

optional1 : Forms.Field.Internal.Fields comparable -> comparable -> a -> (String -> FieldValidation err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates an optional Field (non-accumulative)

optionalWithMaybe1 : Forms.Field.Internal.Fields comparable -> comparable -> (String -> FieldValidation err a) -> FormValidation comparable err (Maybe a -> b) -> FormValidation comparable err b

Validates an optional Field with Maybe (non-accumulative)

discardable1 : Forms.Field.Internal.Fields comparable -> comparable -> (Forms.Value.Internal.Value -> FieldValidation err a) -> FormValidation comparable err b -> FormValidation comparable err b

Validates a discardable Field (non-accumulative)

twoFields1 : Forms.Field.Internal.Fields comparable -> comparable -> comparable -> (Forms.Value.Internal.Value -> Forms.Value.Internal.Value -> FieldValidation err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates two Field together (non-accumulative)

fieldgroup1 : Forms.Field.Internal.Fields comparable -> comparable -> (Forms.Field.Internal.Fields comparable -> FormValidation comparable err a) -> FormValidation comparable err (a -> b) -> FormValidation comparable err b

Validates a fieldgroup (non-accumulative)