[{"name":"FancyForms.Form","comment":" FancyForms is a library for building forms in Elm. It is designed with the following goals in mind:\n\n1.  **Type saftey**: Data collected in the forms will be returned directly into a user provided type.\n2.  **Ease of use**: No matter how complex the form is, it will only need **one** `Msg` and **one** field on the model.\n3.  **Customization**: Users can provide their own widgets and custom validations.\n4.  **CSS Agnostic**: Adapts to any CSS framework.\n5.  **Composable**: Smaller forms can be combined into larger forms.\n6.  **I18n**: Internationalization is supported by avoiding hard coded strings.\n\n\n# Definition\n\n@docs Form, form, field, Field, isValid, validate, FieldWithErrors, PartialForm\n\n\n# Wiring\n\n@docs Msg, customEvent, getCustomEvent, init, update, render, extract\n\n\n# List fields\n\n@docs listField, FieldWithRemoveButton, ListWithAddButton\n\n\n# Fields with Variants\n\n@docs fieldWithVariants, Variant, Variants\n\n\n# Composition\n\n@docs toWidget, wrap\n\n","unions":[{"name":"Msg","comment":" The message type for the form.\n","args":[],"cases":[]}],"aliases":[{"name":"Field","comment":" The type of a field in the form.\n","args":["a","customError"],"type":"{ id : FancyForms.FormState.FieldId, value : FancyForms.FormState.FormState -> a, errors : FancyForms.FormState.FormState -> List.List (FancyForms.FormState.Error customError), view : FancyForms.FormState.FormState -> List.List (Html.Html FancyForms.Form.Msg), multiple : Basics.Bool }"},{"name":"FieldWithErrors","comment":" A function that recieves the markup of a field and combines with a list of errors.\n","args":["customError"],"type":"List.List (FancyForms.FormState.Error customError) -> List.List (Html.Html FancyForms.Form.Msg) -> List.List (Html.Html FancyForms.Form.Msg)"},{"name":"FieldWithRemoveButton","comment":" A function that recieves the markup of a list item and combines it with a butoon to remive it from the List.\n","args":["msg"],"type":"msg -> List.List (Html.Html msg) -> List.List (Html.Html msg)"},{"name":"Form","comment":" A form that collects a value of type `data` and potentially produces errors of type `customError`.\n","args":["data","customError"],"type":"FancyForms.Form.PartialForm { view : FancyForms.FormState.FormState -> List.List (FancyForms.FormState.Error customError) -> List.List (Html.Html FancyForms.Form.Msg), combine : FancyForms.FormState.FormState -> data } customError data"},{"name":"ListWithAddButton","comment":" A function that recieves the markup of a field and combines it with a button to add a new item.\n","args":["msg"],"type":"msg -> List.List (Html.Html msg) -> List.List (Html.Html msg)"},{"name":"PartialForm","comment":" Represents a form that still needs it's fields to be declared.\nOnce all the fields that the view function consumes are declared it\nis not \"partial\" anymore.\n","args":["f","customError","data"],"type":"{ fn : f, count : Basics.Int, updates : Dict.Dict FancyForms.FormState.FieldId (FancyForms.FormState.SubfieldId -> FancyForms.FormState.FieldOperation -> Json.Encode.Value -> ( Json.Encode.Value, FancyForms.FormState.Effect )), fieldWithErrors : FancyForms.Form.FieldWithErrors customError, validator : FancyForms.FormState.Validator data customError, blur : FancyForms.FormState.FormState -> FancyForms.FormState.FormState, domId : FancyForms.FormState.DomId, isConsistent : FancyForms.FormState.FormState -> Basics.Bool, initWithData : data -> FancyForms.FormState.FormState -> FancyForms.FormState.FormState }"},{"name":"Variant","comment":" A variant for widgets with a \"select\" notion.\n","args":["a"],"type":"{ value : a, id : String.String, label : String.String }"},{"name":"Variants","comment":" A nonempty list of variants.\n","args":["a"],"type":"List.Nonempty.Nonempty (FancyForms.Form.Variant a)"}],"values":[{"name":"customEvent","comment":" Since all messages in the form have to be serializable to JSON, we just use a JSON\nvalue for msgs from the app. The dev needs to provide their own en-/decoder.\nIt's a bit hacky but having to pass another type and decoders through the forms makes\neverything more complicated.\n","type":"Json.Encode.Value -> FancyForms.Form.Msg"},{"name":"extract","comment":" Returns the result of the `combine` function aka the current state of the form.\n","type":"FancyForms.Form.Form data customError -> FancyForms.FormState.FormState -> data"},{"name":"field","comment":" Adds a new field with the given widget to the form\n","type":"(data -> value) -> FancyForms.FormState.Widget widgetModel msg value customError -> FancyForms.Form.PartialForm (FancyForms.Form.Field value customError -> c) customError data -> FancyForms.Form.PartialForm c customError data"},{"name":"fieldWithVariants","comment":" Adds a new field to with different variants to the form.\nEach variant is represented by a label and a sub form.\n\nThe function takes the following arguments:\n\n1.  A widget to select the variant\n2.  The default variant\n3.  A list of other variants\n\n","type":"(data -> value) -> (FancyForms.Form.Variants String.String -> FancyForms.FormState.Widget model msg String.String customError) -> ( String.String, FancyForms.Form.Form value customError ) -> List.List ( String.String, FancyForms.Form.Form value customError ) -> (value -> String.String) -> FancyForms.Form.PartialForm (FancyForms.Form.Field value customError -> c) customError data -> FancyForms.Form.PartialForm c customError data"},{"name":"form","comment":" Defines a new form that fields can be added to.\nTakes four arguments:\n1, A unique id for the form to be used as id in the DOM\n\n1.  A validator function that takes the form data and returns a list of errors\n\n2.  A function that receives the fields and returns the `view` and `combine` functions\n\n3.  A function that receives the markup of a field and combines it with a list of errors\n\n        myForm : Form Int ()\n        myForm =\n            Form.form\n                (\\errors_ html -> html)\n                (\\data -> [])\n                \"minimal-example\"\n                (\\amount ->\n                    { view = \\formState _ -> amount.view formState\n                    , combine = \\formState -> amount.value formState\n                    }\n                )\n                |> field (integerInput [])\n\n","type":"FancyForms.Form.FieldWithErrors customError -> FancyForms.FormState.Validator data customError -> FancyForms.FormState.DomId -> a -> FancyForms.Form.PartialForm a customError data"},{"name":"getCustomEvent","comment":" You can use this function to extract the custom event from the message in your\nupdate function.\n","type":"FancyForms.Form.Msg -> Maybe.Maybe Json.Encode.Value"},{"name":"init","comment":" Initializes a form state with the default values\n","type":"FancyForms.Form.Form data customError -> data -> FancyForms.FormState.FormState"},{"name":"isValid","comment":" Returns true if the data entered in the form is valid\n","type":"FancyForms.Form.Form data customError -> FancyForms.FormState.FormState -> Basics.Bool"},{"name":"listField","comment":" Adds a field to the form where the user can add and remove elements.\n\nThe first argument is a `ListWithAddButton` function that cobines the inout list with a button to add a new element.\n\nThe second argument is a `FieldWithRemoveButton` function that combines one item with a button to remove it.\n\nThe third argument is the widget to use for each element in the list.\n\n","type":"FancyForms.Form.ListWithAddButton FancyForms.Form.Msg -> FancyForms.Form.FieldWithRemoveButton FancyForms.Form.Msg -> value -> (data -> List.List value) -> FancyForms.FormState.Widget model msg value customError -> { a | fn : FancyForms.Form.Field (List.List value) customError -> b, count : Basics.Int, updates : Dict.Dict String.String (FancyForms.FormState.SubfieldId -> FancyForms.FormState.FieldOperation -> Json.Encode.Value -> ( Json.Encode.Value, FancyForms.FormState.Effect )), fieldWithErrors : FancyForms.Form.FieldWithErrors customError, validator : e, blur : c -> FancyForms.FormState.FormState, domId : FancyForms.FormState.DomId, isConsistent : FancyForms.FormState.FormState -> Basics.Bool, initWithData : data -> FancyForms.FormState.FormState -> FancyForms.FormState.FormState } -> { fn : b, count : Basics.Int, updates : Dict.Dict String.String (FancyForms.FormState.SubfieldId -> FancyForms.FormState.FieldOperation -> Json.Encode.Value -> ( Json.Encode.Value, FancyForms.FormState.Effect )), fieldWithErrors : FancyForms.Form.FieldWithErrors customError, validator : e, blur : c -> FancyForms.FormState.FormState, domId : FancyForms.FormState.DomId, isConsistent : FancyForms.FormState.FormState -> Basics.Bool, initWithData : data -> FancyForms.FormState.FormState -> FancyForms.FormState.FormState }"},{"name":"render","comment":" Takes the following three arguments to display a form:\n\n1.  a function to turn the forms messages into a `Msg` of the application.\n\n2.  the form\n\n3.  the current state of the form\n\n    type Msg = ... | ForForm Form.Msg | ...\n    type alias Model = { ... , formState : FormState, .. }\n    myForm = Form.form ...\n\n    view model =\n    div [] <| Form.render ForForm myForm model.formState\n\n","type":"(FancyForms.Form.Msg -> msg) -> FancyForms.Form.Form a customError -> FancyForms.FormState.FormState -> List.List (Html.Html msg)"},{"name":"toWidget","comment":" Converts a form to a widget.\n","type":"FancyForms.Form.Form a customError -> FancyForms.FormState.Widget FancyForms.FormState.FormState FancyForms.Form.Msg a customError"},{"name":"update","comment":" Updates the form state based on the form message.\n","type":"FancyForms.Form.Form a customError -> FancyForms.Form.Msg -> FancyForms.FormState.FormState -> FancyForms.FormState.FormState"},{"name":"validate","comment":" Adds a validator to a widget.\n","type":"List.List (FancyForms.FormState.Validator value customError) -> FancyForms.FormState.Widget model msg value customError -> FancyForms.FormState.Widget model msg value customError"},{"name":"wrap","comment":" Creates a new `Widget` that's decorated with the given function.\n","type":"FancyForms.FormState.Widget widgetModel msg value customError -> (FancyForms.FormState.DomId -> List.List (Html.Html msg) -> List.List (Html.Html msg)) -> FancyForms.FormState.Widget widgetModel msg value customError"}],"binops":[]},{"name":"FancyForms.FormState","comment":" Exposes various types used to track state of the form.\n\n\n# Types used in the declaration of forms\n\n@docs DomId, Error, FormState, Validator, Widget\n\n\n# Helper to construct forms or modify state\n\n@docs alwaysValid, blurAll, init\n\n\n# Advanced helpers to cunstruc widgets from scratch\n\n@docs blurChildren, Effect, FieldId, FieldOperation, FieldStatus, SubfieldId, UpdateResult, encodedUpdate, formStateDecoder, formStateEncode, justChanged, justChangedInternally, read, subId, updateFieldStatus, wasAtLeast, withBlur, withFocus, write, withInnerAttributes, noAttributes\n\n","unions":[{"name":"Effect","comment":" Specifies the effect of a field with relation to the focus state.\n","args":[],"cases":[["NoEffect",[]],["WasFocused",[]],["WasChanged",[]],["WasBlurred",[]]]},{"name":"Error","comment":" A type for errors that can be generated by a `Validator`\n","args":["customError"],"cases":[["NotValid",[]],["MustNotBeBlank",[]],["MustBeGreaterThan",["String.String"]],["MustBeLesserThan",["String.String"]],["CustomError",["customError"]]]},{"name":"FieldOperation","comment":" Specifies the operation to perform on a field. `Add` and `Remove` are\nused for list fields.\n","args":[],"cases":[["Add",[]],["Remove",[]],["Update",["Json.Encode.Value"]]]},{"name":"FieldStatus","comment":" The status of a field. We'll only expose the result of a field validation after it has been blurred.\n","args":[],"cases":[["NotVisited",[]],["Focused",[]],["Changed",[]],["Blurred",[]]]},{"name":"FormState","comment":" The state of the form. Stores all the values and the status of each field.\n","args":[],"cases":[["FormState",["{ parentDomId : FancyForms.FormState.DomId, values : Dict.Dict FancyForms.FormState.FieldId Json.Encode.Value, fieldStatus : Dict.Dict FancyForms.FormState.FieldId FancyForms.FormState.FieldStatus, allBlurred : Basics.Bool }"]]]},{"name":"SubfieldId","comment":" List fields need an index additional to the FieldId to know which\nlist item to update.\n","args":[],"cases":[["SingleValue",[]],["ArrayElement",["Basics.Int"]]]}],"aliases":[{"name":"DomId","comment":" A unique identifier for a field in a form.\n","args":[],"type":"String.String"},{"name":"FieldId","comment":" A unique identifier for a field in a form.\n","args":[],"type":"String.String"},{"name":"UpdateResult","comment":" Is returned from the `update` function of a `Widget`\n","args":["model"],"type":"{ model : model, effect : FancyForms.FormState.Effect }"},{"name":"Validator","comment":" A validator is a function that can be used to validate the value of a form or a widget.\n","args":["a","e"],"type":"a -> List.List (FancyForms.FormState.Error e)"},{"name":"Widget","comment":" A widget that can be used to create a form field.\n","args":["model","msg","value","customError"],"type":"{ init : value -> model, default : value, value : model -> value, validate : FancyForms.FormState.Validator value customError, isConsistent : model -> Basics.Bool, view : FancyForms.FormState.DomId -> List.List (Html.Attribute msg) -> model -> List.List (Html.Html msg), update : msg -> model -> FancyForms.FormState.UpdateResult model, encodeMsg : msg -> Json.Encode.Value, decoderMsg : Json.Decode.Decoder msg, encodeModel : model -> Json.Encode.Value, decoderModel : Json.Decode.Decoder model, blur : model -> model, innerAttributes : List.List (FancyForms.FormState.Error customError) -> value -> List.List (Html.Attribute msg) }"}],"values":[{"name":"alwaysValid","comment":" Creates a validator that always succeeds.\n\nUseful for forms that fully rely on per-field validations.\n\n","type":"a -> List.List (FancyForms.FormState.Error e)"},{"name":"blurAll","comment":" Marks all fields as blurred. This is needed to show all errors when trying to submit a\nform without the user having visited all fields.\n","type":"FancyForms.FormState.FormState -> FancyForms.FormState.FormState"},{"name":"blurChildren","comment":" Internal: Used to recursively blur child fields.\n","type":"FancyForms.FormState.FieldId -> FancyForms.FormState.Widget model msg value customError -> FancyForms.FormState.FormState -> FancyForms.FormState.FormState"},{"name":"encodedUpdate","comment":" Encodes the update for the given field.\n","type":"FancyForms.FormState.Widget model msg value customError -> FancyForms.FormState.SubfieldId -> FancyForms.FormState.FieldOperation -> Json.Encode.Value -> Json.Encode.Value"},{"name":"formStateDecoder","comment":" Decodes a form state from a JSON value\n","type":"Json.Decode.Decoder FancyForms.FormState.FormState"},{"name":"formStateEncode","comment":" Encodes a form state into a JSON value\n","type":"FancyForms.FormState.FormState -> Json.Encode.Value"},{"name":"init","comment":" Creates a new form state with the given values.\n","type":"Dict.Dict FancyForms.FormState.FieldId Json.Encode.Value -> FancyForms.FormState.DomId -> FancyForms.FormState.FormState"},{"name":"justChanged","comment":" Wraps the given model with the indication that the field was changed in a way that it must also have been focused.\n","type":"model -> FancyForms.FormState.UpdateResult model"},{"name":"justChangedInternally","comment":" Wraps the given model with the indication that the field was changed but didn't change the focus.\n","type":"model -> FancyForms.FormState.UpdateResult model"},{"name":"noAttributes","comment":" The default for a `Widget`\n","type":"List.List (FancyForms.FormState.Error customError) -> value -> List.List (Html.Attribute msg)"},{"name":"read","comment":" Reads the value for the given field.\n","type":"FancyForms.FormState.FieldId -> FancyForms.FormState.FormState -> Json.Encode.Value"},{"name":"subId","comment":" Calculates the dom id for the given field and subfield.\n","type":"FancyForms.FormState.DomId -> FancyForms.FormState.FieldId -> FancyForms.FormState.SubfieldId -> FancyForms.FormState.DomId"},{"name":"updateFieldStatus","comment":" Updates the status of a field based on an effect\n","type":"FancyForms.FormState.FieldStatus -> FancyForms.FormState.Effect -> FancyForms.FormState.FieldStatus"},{"name":"wasAtLeast","comment":" Helper to check if a field was visited\n","type":"FancyForms.FormState.FieldStatus -> FancyForms.FormState.FieldId -> FancyForms.FormState.FormState -> Basics.Bool"},{"name":"withBlur","comment":" Wraps the given model with the indication that the field was blurred.\n","type":"model -> FancyForms.FormState.UpdateResult model"},{"name":"withFocus","comment":" Wraps the given model with the indication that the field was focused.\n","type":"model -> FancyForms.FormState.UpdateResult model"},{"name":"withInnerAttributes","comment":" You can provide a function that generates a list of attributes for the inner widget.\nThis function can use the current value and errors to generate the attributes.\n","type":"(List.List (FancyForms.FormState.Error customError) -> value -> List.List (Html.Attribute msg)) -> FancyForms.FormState.Widget model msg value customError -> FancyForms.FormState.Widget model msg value customError"},{"name":"write","comment":" Updates the value for the given field.\n","type":"FancyForms.FormState.FieldId -> FancyForms.FormState.SubfieldId -> FancyForms.FormState.FormState -> Json.Encode.Value -> FancyForms.FormState.FormState"}],"binops":[]},{"name":"FancyForms.Widgets.Checkbox","comment":" Checkbox widget\n\n@docs checkbox, BoolInput\n\n","unions":[],"aliases":[{"name":"BoolInput","comment":" Signature for an input that collects a `Bool` value\n","args":["customError"],"type":"FancyForms.FormState.Widget Basics.Bool FancyForms.Widgets.Checkbox.Msg Basics.Bool customError"}],"values":[{"name":"checkbox","comment":" A checkbox widget the collects a `Bool` value\n","type":"FancyForms.Widgets.Checkbox.BoolInput customError"}],"binops":[]},{"name":"FancyForms.Widgets.Date","comment":" An date input widget.\n\n@docs dateInput, DateInput, Msg\n\n","unions":[{"name":"Msg","comment":" Messages that can be sent to the date input\n","args":[],"cases":[]}],"aliases":[{"name":"DateInput","comment":" Signature for an input widget that collects a `Date` value\n","args":["customError"],"type":"FancyForms.FormState.Widget FancyForms.Widgets.Date.Model FancyForms.Widgets.Date.Msg Date.Date customError"}],"values":[{"name":"dateInput","comment":" A widget that collects an `Date`\n","type":"List.List (Html.Attribute FancyForms.Widgets.Date.Msg) -> FancyForms.Widgets.Date.DateInput customError"}],"binops":[]},{"name":"FancyForms.Widgets.Dropdown","comment":" A dropdown widget.\n\n@docs dropdown, SelectWidget\n\n","unions":[],"aliases":[{"name":"SelectWidget","comment":" Signature for a widget that lets the user select a value from a\nlist of variants.\n","args":["a","customError"],"type":"FancyForms.FormState.Widget String.String FancyForms.Widgets.Dropdown.Msg a customError"}],"values":[{"name":"dropdown","comment":" Returns a widget that lets the user select a value from a list of\nvariants.\n","type":"FancyForms.Form.Variants a -> FancyForms.Widgets.Dropdown.SelectWidget a customError"}],"binops":[]},{"name":"FancyForms.Widgets.Float","comment":" An float input widget.\n\n@docs floatInput, FloatInput, Msg\n\n\n# Validators\n\n@docs greaterThan, lesserThan\n\n","unions":[{"name":"Msg","comment":" Messages that can be sent to the float input\n","args":[],"cases":[]}],"aliases":[{"name":"FloatInput","comment":" Signature of an input widget that collects a `Float`\n","args":["customError"],"type":"FancyForms.FormState.Widget FancyForms.Widgets.Float.Model FancyForms.Widgets.Float.Msg Basics.Float customError"}],"values":[{"name":"floatInput","comment":" A widget that collects an `Float`\n","type":"List.List (Html.Attribute FancyForms.Widgets.Float.Msg) -> FancyForms.Widgets.Float.FloatInput customError"},{"name":"greaterThan","comment":" A validator function that ensures the value is greater than `x`\n","type":"Basics.Float -> Basics.Float -> List.List (FancyForms.FormState.Error customError)"},{"name":"lesserThan","comment":" A validator function that ensures the value is less than `x`\n","type":"Basics.Float -> Basics.Float -> List.List (FancyForms.FormState.Error customError)"}],"binops":[]},{"name":"FancyForms.Widgets.Int","comment":" An integer input widget.\n\n@docs integerInput, IntInput, Msg\n\n\n# Validators\n\n@docs greaterThan, lesserThan\n\n","unions":[{"name":"Msg","comment":" Messages for the `IntInput`\n","args":[],"cases":[]}],"aliases":[{"name":"IntInput","comment":" Signature for an input widget that collects an `Int`\n","args":["customError"],"type":"FancyForms.FormState.Widget FancyForms.Widgets.Int.Model FancyForms.Widgets.Int.Msg Basics.Int customError"}],"values":[{"name":"greaterThan","comment":" A validator function that ensures the value is greater than `x`\n","type":"Basics.Int -> Basics.Int -> List.List (FancyForms.FormState.Error customError)"},{"name":"integerInput","comment":" A widget that collects an `Int`\n","type":"List.List (Html.Attribute FancyForms.Widgets.Int.Msg) -> FancyForms.Widgets.Int.IntInput customError"},{"name":"lesserThan","comment":" A validator function that ensures the value is less than `x`\n","type":"Basics.Int -> Basics.Int -> List.List (FancyForms.FormState.Error customError)"}],"binops":[]},{"name":"FancyForms.Widgets.RadioButtons","comment":" A widget that lets the user make a selection based on radio buttons\n\n@docs radioButtons\n\n","unions":[],"aliases":[],"values":[{"name":"radioButtons","comment":" Returns a widget that lets the user select a value from a list of\nvariants with radio buttons.\n","type":"FancyForms.Form.Variants a -> FancyForms.Widgets.Dropdown.SelectWidget a customError"}],"binops":[]},{"name":"FancyForms.Widgets.Text","comment":" A text input widget\n\n@docs textInput, TextInput, Msg\n\n\n# Validators\n\n@docs notBlank\n\n","unions":[{"name":"Msg","comment":" Messages that can be sent to the text input\n","args":[],"cases":[]}],"aliases":[{"name":"TextInput","comment":" Signature for a text input widget\n","args":["customError"],"type":"FancyForms.FormState.Widget String.String FancyForms.Widgets.Text.Msg String.String customError"}],"values":[{"name":"notBlank","comment":" A validator function that ensures that the given string is not empty.\n","type":"String.String -> List.List (FancyForms.FormState.Error customError)"},{"name":"textInput","comment":" A text input widget\n","type":"List.List (Html.Attribute FancyForms.Widgets.Text.Msg) -> FancyForms.Widgets.Text.TextInput customError"}],"binops":[]}]