{-# OPTIONS_GHC -Wno-orphans #-}
{-# OPTIONS_GHC -Wno-missing-fields #-}
{-# language DefaultSignatures #-}
{-# language DeriveGeneric #-}
{-# language LambdaCase #-}
{-# language OverloadedStrings #-}
{-# language StandaloneDeriving #-}
{-# language TypeOperators #-}

{- |
Generic `Yesod` input form generation and related utility functions.
-}

module FlexTask.Generic.Form
  (
    -- * Data Types
    Alignment(..)
  , FieldInfo
  , SingleChoiceSelection
  , MultipleChoiceSelection
  , Hidden(..)
  , SingleInputList(..)
    -- * Type Classes
  , BaseForm(..)
  , Formify(..)
  , formify
  , formifyComponents
  , formifyComponentsFlat
    -- * Anonymous Enum Type Builders and Accessors.
  , getAnswer
  , getAnswers
  , multipleChoiceAnswer
  , multipleChoiceEmpty
  , singleChoiceAnswer
  , singleChoiceEmpty

    -- * Field Builders
  , buttons
  , buttonsEnum
  , dropdown
  , dropdownEnum
  , list
  , listWithoutLabels
  , single

    -- * Formify Convenience Functions
  , formifyInstanceBasicField
  , formifyInstanceOptionalField
  , formifyInstanceSingleChoice
  , formifyInstanceMultiChoice
  ) where


import Data.List.Extra      (intercalate, nubSort, uncons, unsnoc)
import Data.Tuple.Extra     (first)
import Data.Maybe           (fromMaybe)
import GHC.Generics         (Generic(..), K1(..), M1(..), (:*:)(..))
import GHC.Utils.Misc       (equalLength)
import Data.Text            (Text, pack, unpack)
import Yesod

import FlexTask.Widgets
  ( checkboxField
  , horizontalRadioField
  , joinRenders
  , renderForm
  )
import FlexTask.YesodConfig (FlexForm(..), Handler, Rendered, Widget)




{- |
Data type representing a prebuilt input field.
This type is used to determine the structure of a generated form.
The form is represented by a @[[FieldInfo]]@ type value.
Each FieldInfo value is an individual form element.
Inner lists represent the rows of the form.
All FieldInfo values in an inner list are rendered besides each other.
The outer list represents the columns of the form.
Inner lists are rendered below each other.

__Examples__

Input

@
[[Single \"field1\", Single \"field2\"]]
@

Renders as:

@
field1     field2
@

Input

@
[[single \"field1\"], [single \"field2\"]]
@

Renders as:

@
field1

field2
@

__Caution: Not all horizontal alignments work as one would expect.__
__If an element uses inner `Alignment` parameters,__
__then the next form will only be rendered besides the last form component of the former.__

Input

@
[[listWithoutLabels Vertical 2 []],[listWithoutLabels Vertical 2 []]]
@

will __not__ result in

@
list11      list21

list12      list22
@

but instead in

@
list11

list12     list21

list22
@
-}
data FieldInfo
  = Single (FieldSettings FlexForm)
  | List Alignment [FieldSettings FlexForm]
  | ChoicesDropdown (FieldSettings FlexForm) [SomeMessage FlexForm]
  | ChoicesButtons Alignment (FieldSettings FlexForm) [SomeMessage FlexForm]
  | InternalListElem (FieldSettings FlexForm)
  deriving (Int -> FieldInfo -> ShowS
[FieldInfo] -> ShowS
FieldInfo -> String
(Int -> FieldInfo -> ShowS)
-> (FieldInfo -> String)
-> ([FieldInfo] -> ShowS)
-> Show FieldInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FieldInfo -> ShowS
showsPrec :: Int -> FieldInfo -> ShowS
$cshow :: FieldInfo -> String
show :: FieldInfo -> String
$cshowList :: [FieldInfo] -> ShowS
showList :: [FieldInfo] -> ShowS
Show)


-- For tests; TODO: Move completely into test suite
deriving instance Show (FieldSettings FlexForm)

instance Show (SomeMessage FlexForm) where
  show :: SomeMessage FlexForm -> String
show SomeMessage FlexForm
m = Char
'('Char -> ShowS
forall a. a -> [a] -> [a]
: String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((Text -> String) -> [Text] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Text -> String
unpack
      [ Text
"German: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inLang Text
"de"
      , Text
"English: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
inLang Text
"en"
      ]
      ) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
    where
      inLang :: Text -> Text
inLang Text
l = FlexForm -> [Text] -> SomeMessage FlexForm -> Text
forall master message.
RenderMessage master message =>
master -> [Text] -> message -> Text
renderMessage FlexForm{} [Text
l] SomeMessage FlexForm
m


-- | Inner alignment of input field elements.
data Alignment = Horizontal | Vertical deriving (Alignment -> Alignment -> Bool
(Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool) -> Eq Alignment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Alignment -> Alignment -> Bool
== :: Alignment -> Alignment -> Bool
$c/= :: Alignment -> Alignment -> Bool
/= :: Alignment -> Alignment -> Bool
Eq,Int -> Alignment -> ShowS
[Alignment] -> ShowS
Alignment -> String
(Int -> Alignment -> ShowS)
-> (Alignment -> String)
-> ([Alignment] -> ShowS)
-> Show Alignment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Alignment -> ShowS
showsPrec :: Int -> Alignment -> ShowS
$cshow :: Alignment -> String
show :: Alignment -> String
$cshowList :: [Alignment] -> ShowS
showList :: [Alignment] -> ShowS
Show)


-- | Wrapper type for generating hidden fields.
newtype Hidden a = Hidden {forall a. Hidden a -> a
getHidden :: a} deriving (Hidden a -> Hidden a -> Bool
(Hidden a -> Hidden a -> Bool)
-> (Hidden a -> Hidden a -> Bool) -> Eq (Hidden a)
forall a. Eq a => Hidden a -> Hidden a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Hidden a -> Hidden a -> Bool
== :: Hidden a -> Hidden a -> Bool
$c/= :: forall a. Eq a => Hidden a -> Hidden a -> Bool
/= :: Hidden a -> Hidden a -> Bool
Eq,Int -> Hidden a -> ShowS
[Hidden a] -> ShowS
Hidden a -> String
(Int -> Hidden a -> ShowS)
-> (Hidden a -> String) -> ([Hidden a] -> ShowS) -> Show (Hidden a)
forall a. Show a => Int -> Hidden a -> ShowS
forall a. Show a => [Hidden a] -> ShowS
forall a. Show a => Hidden a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Hidden a -> ShowS
showsPrec :: Int -> Hidden a -> ShowS
$cshow :: forall a. Show a => Hidden a -> String
show :: Hidden a -> String
$cshowList :: forall a. Show a => [Hidden a] -> ShowS
showList :: [Hidden a] -> ShowS
Show)


-- | Wrapper type for lists. Use for a single field list input.
newtype SingleInputList a = SingleInputList {forall a. SingleInputList a -> [a]
getList :: [a]} deriving (SingleInputList a -> SingleInputList a -> Bool
(SingleInputList a -> SingleInputList a -> Bool)
-> (SingleInputList a -> SingleInputList a -> Bool)
-> Eq (SingleInputList a)
forall a. Eq a => SingleInputList a -> SingleInputList a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => SingleInputList a -> SingleInputList a -> Bool
== :: SingleInputList a -> SingleInputList a -> Bool
$c/= :: forall a. Eq a => SingleInputList a -> SingleInputList a -> Bool
/= :: SingleInputList a -> SingleInputList a -> Bool
Eq,Int -> SingleInputList a -> ShowS
[SingleInputList a] -> ShowS
SingleInputList a -> String
(Int -> SingleInputList a -> ShowS)
-> (SingleInputList a -> String)
-> ([SingleInputList a] -> ShowS)
-> Show (SingleInputList a)
forall a. Show a => Int -> SingleInputList a -> ShowS
forall a. Show a => [SingleInputList a] -> ShowS
forall a. Show a => SingleInputList a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> SingleInputList a -> ShowS
showsPrec :: Int -> SingleInputList a -> ShowS
$cshow :: forall a. Show a => SingleInputList a -> String
show :: SingleInputList a -> String
$cshowList :: forall a. Show a => [SingleInputList a] -> ShowS
showList :: [SingleInputList a] -> ShowS
Show)

{- |
Generic single choice answer type.
Use if you want a 'choose one of multiple' style input
without caring about the underlying type.
-}
newtype SingleChoiceSelection = SingleChoiceSelection
  {SingleChoiceSelection -> Maybe Int
getAnswer :: Maybe Int -- ^ Retrieve the selected option. @Nothing@ if none.
  } deriving (Int -> SingleChoiceSelection -> ShowS
[SingleChoiceSelection] -> ShowS
SingleChoiceSelection -> String
(Int -> SingleChoiceSelection -> ShowS)
-> (SingleChoiceSelection -> String)
-> ([SingleChoiceSelection] -> ShowS)
-> Show SingleChoiceSelection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SingleChoiceSelection -> ShowS
showsPrec :: Int -> SingleChoiceSelection -> ShowS
$cshow :: SingleChoiceSelection -> String
show :: SingleChoiceSelection -> String
$cshowList :: [SingleChoiceSelection] -> ShowS
showList :: [SingleChoiceSelection] -> ShowS
Show,SingleChoiceSelection -> SingleChoiceSelection -> Bool
(SingleChoiceSelection -> SingleChoiceSelection -> Bool)
-> (SingleChoiceSelection -> SingleChoiceSelection -> Bool)
-> Eq SingleChoiceSelection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SingleChoiceSelection -> SingleChoiceSelection -> Bool
== :: SingleChoiceSelection -> SingleChoiceSelection -> Bool
$c/= :: SingleChoiceSelection -> SingleChoiceSelection -> Bool
/= :: SingleChoiceSelection -> SingleChoiceSelection -> Bool
Eq,(forall x. SingleChoiceSelection -> Rep SingleChoiceSelection x)
-> (forall x. Rep SingleChoiceSelection x -> SingleChoiceSelection)
-> Generic SingleChoiceSelection
forall x. Rep SingleChoiceSelection x -> SingleChoiceSelection
forall x. SingleChoiceSelection -> Rep SingleChoiceSelection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SingleChoiceSelection -> Rep SingleChoiceSelection x
from :: forall x. SingleChoiceSelection -> Rep SingleChoiceSelection x
$cto :: forall x. Rep SingleChoiceSelection x -> SingleChoiceSelection
to :: forall x. Rep SingleChoiceSelection x -> SingleChoiceSelection
Generic)
-- | Same as `SingleChoiceSelection`, but for multiple choice input.
newtype MultipleChoiceSelection = MultipleChoiceSelection
  { MultipleChoiceSelection -> [Int]
getAnswers :: [Int] -- ^ Retrieve the list of selected options. @[]@ if none.
  } deriving (Int -> MultipleChoiceSelection -> ShowS
[MultipleChoiceSelection] -> ShowS
MultipleChoiceSelection -> String
(Int -> MultipleChoiceSelection -> ShowS)
-> (MultipleChoiceSelection -> String)
-> ([MultipleChoiceSelection] -> ShowS)
-> Show MultipleChoiceSelection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MultipleChoiceSelection -> ShowS
showsPrec :: Int -> MultipleChoiceSelection -> ShowS
$cshow :: MultipleChoiceSelection -> String
show :: MultipleChoiceSelection -> String
$cshowList :: [MultipleChoiceSelection] -> ShowS
showList :: [MultipleChoiceSelection] -> ShowS
Show,MultipleChoiceSelection -> MultipleChoiceSelection -> Bool
(MultipleChoiceSelection -> MultipleChoiceSelection -> Bool)
-> (MultipleChoiceSelection -> MultipleChoiceSelection -> Bool)
-> Eq MultipleChoiceSelection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MultipleChoiceSelection -> MultipleChoiceSelection -> Bool
== :: MultipleChoiceSelection -> MultipleChoiceSelection -> Bool
$c/= :: MultipleChoiceSelection -> MultipleChoiceSelection -> Bool
/= :: MultipleChoiceSelection -> MultipleChoiceSelection -> Bool
Eq,(forall x.
 MultipleChoiceSelection -> Rep MultipleChoiceSelection x)
-> (forall x.
    Rep MultipleChoiceSelection x -> MultipleChoiceSelection)
-> Generic MultipleChoiceSelection
forall x. Rep MultipleChoiceSelection x -> MultipleChoiceSelection
forall x. MultipleChoiceSelection -> Rep MultipleChoiceSelection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MultipleChoiceSelection -> Rep MultipleChoiceSelection x
from :: forall x. MultipleChoiceSelection -> Rep MultipleChoiceSelection x
$cto :: forall x. Rep MultipleChoiceSelection x -> MultipleChoiceSelection
to :: forall x. Rep MultipleChoiceSelection x -> MultipleChoiceSelection
Generic)


-- | Value with no option selected.
singleChoiceEmpty :: SingleChoiceSelection
singleChoiceEmpty :: SingleChoiceSelection
singleChoiceEmpty = Maybe Int -> SingleChoiceSelection
SingleChoiceSelection Maybe Int
forall a. Maybe a
Nothing


-- | Value with given number option selected.
singleChoiceAnswer :: Int -> SingleChoiceSelection
singleChoiceAnswer :: Int -> SingleChoiceSelection
singleChoiceAnswer = Maybe Int -> SingleChoiceSelection
SingleChoiceSelection (Maybe Int -> SingleChoiceSelection)
-> (Int -> Maybe Int) -> Int -> SingleChoiceSelection
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int
forall a. a -> Maybe a
Just


-- | Value with no options selected.
multipleChoiceEmpty :: MultipleChoiceSelection
multipleChoiceEmpty :: MultipleChoiceSelection
multipleChoiceEmpty = [Int] -> MultipleChoiceSelection
MultipleChoiceSelection []

{- |
Value with given list of options selected.
The order of list elements is inconsequential.
-}
multipleChoiceAnswer :: [Int] -> MultipleChoiceSelection
multipleChoiceAnswer :: [Int] -> MultipleChoiceSelection
multipleChoiceAnswer = [Int] -> MultipleChoiceSelection
MultipleChoiceSelection ([Int] -> MultipleChoiceSelection)
-> ([Int] -> [Int]) -> [Int] -> MultipleChoiceSelection
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [Int]
forall a. Ord a => [a] -> [a]
nubSort



{- |
Members have a basic Yesod field representing Html input fields.
A `BaseForm` instance of type @a@ is needed for generically producing forms
for @[a]@ and @Maybe a@ types.
An instance can be given manually with the `Field` constructor
or using the `convertField` function on an existing `Field`.
-}
class BaseForm a where
  baseForm :: Field Handler a


instance BaseForm Integer where
  baseForm :: Field Handler Integer
baseForm = Field Handler Integer
forall (m :: * -> *) i.
(Monad m, Integral i, RenderMessage (HandlerSite m) FormMessage) =>
Field m i
intField

instance BaseForm Int where
  baseForm :: Field Handler Int
baseForm = Field Handler Int
forall (m :: * -> *) i.
(Monad m, Integral i, RenderMessage (HandlerSite m) FormMessage) =>
Field m i
intField

instance BaseForm Text where
  baseForm :: Field Handler Text
baseForm = Field Handler Text
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Text
textField


instance BaseForm String where
  baseForm :: Field Handler String
baseForm = (Text -> String)
-> (String -> Text) -> Field Handler Text -> Field Handler String
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> (b -> a) -> Field m a -> Field m b
convertField Text -> String
unpack String -> Text
pack Field Handler Text
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Text
textField


instance BaseForm Textarea where
  baseForm :: Field Handler Textarea
baseForm = Field Handler Textarea
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Textarea
textareaField


instance BaseForm Bool where
  baseForm :: Field Handler Bool
baseForm = Field Handler Bool
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Bool
boolField


instance BaseForm Double where
  baseForm :: Field Handler Double
baseForm = Field Handler Double
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Double
doubleField


instance PathPiece a => PathPiece (Hidden a) where
  fromPathPiece :: Text -> Maybe (Hidden a)
fromPathPiece = (a -> Hidden a) -> Maybe a -> Maybe (Hidden a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Hidden a
forall a. a -> Hidden a
Hidden (Maybe a -> Maybe (Hidden a))
-> (Text -> Maybe a) -> Text -> Maybe (Hidden a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe a
forall s. PathPiece s => Text -> Maybe s
fromPathPiece
  toPathPiece :: Hidden a -> Text
toPathPiece = a -> Text
forall s. PathPiece s => s -> Text
toPathPiece (a -> Text) -> (Hidden a -> a) -> Hidden a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hidden a -> a
forall a. Hidden a -> a
getHidden


instance PathPiece a => BaseForm (Hidden a) where
  baseForm :: Field Handler (Hidden a)
baseForm = Field Handler (Hidden a)
forall (m :: * -> *) p.
(Monad m, PathPiece p,
 RenderMessage (HandlerSite m) FormMessage) =>
Field m p
hiddenField


-- This indicates I should probably change this class to something more succinct.
-- The first function is never used, since it normally handles the parsing.
instance Show a => BaseForm (SingleInputList a) where
  baseForm :: Field Handler (SingleInputList a)
baseForm = (Text -> SingleInputList a)
-> (SingleInputList a -> Text)
-> Field Handler Text
-> Field Handler (SingleInputList a)
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> (b -> a) -> Field m a -> Field m b
convertField Text -> SingleInputList a
forall a. HasCallStack => a
undefined (String -> Text
pack (String -> Text)
-> (SingleInputList a -> String) -> SingleInputList a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ([String] -> String)
-> (SingleInputList a -> [String]) -> SingleInputList a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map a -> String
forall a. Show a => a -> String
show ([a] -> [String])
-> (SingleInputList a -> [a]) -> SingleInputList a -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SingleInputList a -> [a]
forall a. SingleInputList a -> [a]
getList) Field Handler Text
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Text
textField


{- |
Class for generic generation of Html input forms for a given type.
Bodyless instances can be declared for any type instancing Generic.
__Exception: Types with multiple constructors.__
Use utility functions for those or provide your own instance.
-}
class Formify a where
  {- |
  Direct use of this function is not recommended
  due to possible undetected invalidity of the result.
  It should only be used when writing manual instances of `Formify`.
  Use `formify` or its variants instead.
  -}
  formifyImplementation
      :: Maybe a -- ^ Optional default value for form.
      -> [[FieldInfo]] -- ^ Structure and type of form.
      -> ([[FieldInfo]], [[Rendered Widget]]) -- ^ remaining form structure and completed sub-renders.

  default formifyImplementation
      :: (Generic a, GFormify (Rep a))
      => Maybe a
      -> [[FieldInfo]]
      -> ([[FieldInfo]], [[Rendered Widget]])
  formifyImplementation Maybe a
mDefault = Maybe (Rep a Any)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Maybe (Rep a a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall (f :: * -> *) a.
GFormify f =>
Maybe (f a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
gformify (Maybe (Rep a Any)
 -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]]))
-> Maybe (Rep a Any)
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
forall a b. (a -> b) -> a -> b
$ a -> Rep a Any
forall x. a -> Rep a x
forall a x. Generic a => a -> Rep a x
from (a -> Rep a Any) -> Maybe a -> Maybe (Rep a Any)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe a
mDefault



class GFormify f where
  gformify :: Maybe (f a) -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])



instance (GFormify a, GFormify b) => GFormify (a :*: b) where
  gformify :: forall a.
Maybe ((:*:) a b a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
gformify Maybe ((:*:) a b a)
mDefault [[FieldInfo]]
xs = ([[FieldInfo]]
rightRest, [[Rendered Widget]]
[[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
renders)
    where
      (Maybe (a a)
left,Maybe (b a)
right) = case Maybe ((:*:) a b a)
mDefault of
        Maybe ((:*:) a b a)
Nothing        -> (Maybe (a a)
forall a. Maybe a
Nothing,Maybe (b a)
forall a. Maybe a
Nothing)
        Just (a a
a :*: b a
b) -> (a a -> Maybe (a a)
forall a. a -> Maybe a
Just a a
a, b a -> Maybe (b a)
forall a. a -> Maybe a
Just b a
b)
      ([[FieldInfo]]
leftRest, [[Rendered Widget]]
leftRender) = Maybe (a a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Maybe (a a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall (f :: * -> *) a.
GFormify f =>
Maybe (f a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
gformify Maybe (a a)
left [[FieldInfo]]
xs
      ([[FieldInfo]]
rightRest, [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
rightRender) = Maybe (b a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Maybe (b a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall (f :: * -> *) a.
GFormify f =>
Maybe (f a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
gformify Maybe (b a)
right [[FieldInfo]]
rightFieldInfo
      ([[FieldInfo]]
rightFieldInfo,[[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
renders) = case [[FieldInfo]]
leftRest of
        ([]:[[FieldInfo]]
xss) -> ([[FieldInfo]]
xss, [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
leftRender [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall a. [a] -> [a] -> [a]
++ [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
rightRender)
        [[FieldInfo]]
rest   -> ([[FieldInfo]]
rest, [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
ls [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall a. [a] -> [a] -> [a]
++ [[Reader
   Html
   (RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget))]
lastRenderLeft [Reader
   Html
   (RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget))]
-> [Reader
      Html
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget))]
-> [Reader
      Html
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget))]
forall a. [a] -> [a] -> [a]
++ [Reader
   Html
   (RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget))]
firstRenderRight] [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall a. [a] -> [a] -> [a]
++ [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
rs)
      ([[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
ls,[Reader
   Html
   (RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget))]
lastRenderLeft) = ([[Reader
     Html
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget))]],
 [Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))])
-> Maybe
     ([[Reader
          Html
          (RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget))]],
      [Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))])
-> ([[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]],
    [Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))])
forall a. a -> Maybe a -> a
fromMaybe ([[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
leftRender,[]) (Maybe
   ([[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]],
    [Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))])
 -> ([[Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))]],
     [Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]))
-> Maybe
     ([[Reader
          Html
          (RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget))]],
      [Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))])
-> ([[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]],
    [Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))])
forall a b. (a -> b) -> a -> b
$ [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> Maybe
     ([[Reader
          Html
          (RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget))]],
      [Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))])
forall a. [a] -> Maybe ([a], a)
unsnoc [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
leftRender
      ([Reader
   Html
   (RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget))]
firstRenderRight,[[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
rs) = ([Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))],
 [[Reader
     Html
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget))]])
-> Maybe
     ([Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))],
      [[Reader
          Html
          (RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget))]])
-> ([Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall a. a -> Maybe a -> a
fromMaybe ([],[[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
rightRender) (Maybe
   ([Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
 -> ([Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))],
     [[Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))]]))
-> Maybe
     ([Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))],
      [[Reader
          Html
          (RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget))]])
-> ([Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall a b. (a -> b) -> a -> b
$ [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> Maybe
     ([Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))],
      [[Reader
          Html
          (RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget))]])
forall a. [a] -> Maybe (a, [a])
uncons [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
rightRender



instance GFormify a => GFormify (M1 i c a) where
  gformify :: forall a.
Maybe (M1 i c a a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
gformify Maybe (M1 i c a a)
mDefault = Maybe (a a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Maybe (a a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall (f :: * -> *) a.
GFormify f =>
Maybe (f a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
gformify (Maybe (a a)
 -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]]))
-> Maybe (a a)
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
forall a b. (a -> b) -> a -> b
$ M1 i c a a -> a a
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1 (M1 i c a a -> a a) -> Maybe (M1 i c a a) -> Maybe (a a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (M1 i c a a)
mDefault



instance Formify a => GFormify (K1 i a) where
  gformify :: forall a.
Maybe (K1 i a a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
gformify Maybe (K1 i a a)
mDefault = Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Formify a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation (Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]]))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a b. (a -> b) -> a -> b
$ K1 i a a -> a
forall k i c (p :: k). K1 i c p -> c
unK1 (K1 i a a -> a) -> Maybe (K1 i a a) -> Maybe a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (K1 i a a)
mDefault


instance Formify Integer where
  formifyImplementation :: Maybe Integer
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe Integer
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField

instance Formify Int where
  formifyImplementation :: Maybe Int -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe Int -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField

instance Formify Text where
  formifyImplementation :: Maybe Text -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe Text -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField


instance Formify String where
  formifyImplementation :: Maybe String
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe String
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField


instance Formify Textarea where
  formifyImplementation :: Maybe Textarea
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe Textarea
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField


instance Formify Bool where
  formifyImplementation :: Maybe Bool -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe Bool -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField



instance Formify Double where
  formifyImplementation :: Maybe Double
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe Double
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField


instance PathPiece a => Formify (Hidden a) where
  formifyImplementation :: Maybe (Hidden a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe (Hidden a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField


instance Show a => Formify (SingleInputList a) where
  formifyImplementation :: Maybe (SingleInputList a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe (SingleInputList a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField


instance (Formify a, Formify b) => Formify (a,b)

instance (Formify a, Formify b, Formify c) => Formify (a,b,c)

instance (Formify a, Formify b, Formify c, Formify d) => Formify (a,b,c,d)

instance (Formify a, Formify b, Formify c, Formify d, Formify e) => Formify (a,b,c,d,e)

instance (Formify a, Formify b, Formify c, Formify d, Formify e, Formify f) => Formify (a,b,c,d,e,f)


instance {-# Overlappable #-} (BaseForm a, Formify a) => Formify [a] where
  formifyImplementation :: Maybe [a] -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe [a] -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Formify a =>
Maybe [a] -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceList



instance (BaseForm a, Formify a) => Formify (Maybe a) where
  formifyImplementation :: Maybe (Maybe a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe (Maybe a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
BaseForm a =>
Maybe (Maybe a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceOptionalField


instance Formify (Maybe a) => Formify [Maybe a] where
  formifyImplementation :: Maybe [Maybe a]
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = Maybe [Maybe a]
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Formify a =>
Maybe [a] -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceList


instance Formify SingleChoiceSelection where
  formifyImplementation :: Maybe SingleChoiceSelection
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, Int)])
-> Maybe Int
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Eq a =>
([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextSingleChoiceField ([SomeMessage FlexForm] -> [Int] -> [(SomeMessage FlexForm, Int)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Int
1..]) (Maybe Int
 -> [[FieldInfo]]
 -> ([[FieldInfo]],
     [[Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))]]))
-> (Maybe SingleChoiceSelection -> Maybe Int)
-> Maybe SingleChoiceSelection
-> [[FieldInfo]]
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SingleChoiceSelection -> Maybe Int)
-> Maybe SingleChoiceSelection -> Maybe Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
(=<<) SingleChoiceSelection -> Maybe Int
getAnswer


instance Formify MultipleChoiceSelection where
  formifyImplementation :: Maybe MultipleChoiceSelection
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation = ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, Int)])
-> Maybe [Int]
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Eq a =>
([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe [a]
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
renderNextMultipleChoiceField ([SomeMessage FlexForm] -> [Int] -> [(SomeMessage FlexForm, Int)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Int
1..]) (Maybe [Int]
 -> [[FieldInfo]]
 -> ([[FieldInfo]],
     [[Reader
         Html
         (RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget))]]))
-> (Maybe MultipleChoiceSelection -> Maybe [Int])
-> Maybe MultipleChoiceSelection
-> [[FieldInfo]]
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MultipleChoiceSelection -> [Int])
-> Maybe MultipleChoiceSelection -> Maybe [Int]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MultipleChoiceSelection -> [Int]
getAnswers



{- |
This is the main way to build generic forms.
Use in conjunction with `FieldInfo` builders to generate a form.

Will fail if remaining `FieldInfo` structure is not empty,
indicating the form is faulty.


__Examples__

@
formify (Nothing \@Int) [[single \"Age\"]]
@

Renders an input field with /type=number/ attribute, no default value and label /Age/.

@
formify (Just [\"Hallo\", \"Hello\", \"Hola\", \"Ciao\"]) [[listWithoutLabels Vertical 4 [(\"class\",\"helloInput\")]]]
@

Renders a series of four input fields, each for the type String
and organized vertically beneath each other.
They are prefilled with the values given above,
are assigned the Css class \"helloInput\" and have no labels attached to them.

@
formify
  (Nothing \@SingleChoiceSelection)
  [[ buttons
      \"Make your choice\"
      [ \"this one\"
      , \"or rather that one\"
      , \"I just can't decide\"
      ]
  ]]
@

Renders a radio button field with the given title and option labels attached.
No option is selected when the form is loaded.
-}
formify
  :: (Formify a)
  => Maybe a -- ^ Optional default value for form.
  -> [[FieldInfo]] -- ^ Structure of form.
  -> Rendered Widget -- ^ Rendered form.
formify :: forall a. Formify a => Maybe a -> [[FieldInfo]] -> Rendered Widget
formify = ([[Rendered Widget]]
 -> Reader
      Html
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget)))
-> Maybe a
-> [[FieldInfo]]
-> Reader
     Html
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget))
forall a b.
Formify a =>
([[Rendered Widget]] -> b) -> Maybe a -> [[FieldInfo]] -> b
checkAndApply [[Rendered Widget]] -> Rendered Widget
[[Rendered Widget]]
-> Reader
     Html
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget))
joinRenders


{- |
like `formify`, but yields the individual sub-renders instead of a combined form.
Retains the layout structure given by the `FieldInfo` list argument.
This can be used in custom forms to incorporate generated inputs.
-}
formifyComponents :: Formify a => Maybe a -> [[FieldInfo]] -> Rendered [[Widget]]
formifyComponents :: forall a.
Formify a =>
Maybe a -> [[FieldInfo]] -> Rendered [[Widget]]
formifyComponents = ([[Rendered Widget]]
 -> ReaderT
      Html
      Identity
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], [[Widget]])))
-> Maybe a
-> [[FieldInfo]]
-> ReaderT
     Html
     Identity
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], [[Widget]]))
forall a b.
Formify a =>
([[Rendered Widget]] -> b) -> Maybe a -> [[FieldInfo]] -> b
checkAndApply (([[RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([Text], Widget)]]
 -> RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], [[Widget]]))
-> ReaderT
     Html
     Identity
     [[RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget)]]
-> ReaderT
     Html
     Identity
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], [[Widget]]))
forall a b.
(a -> b) -> ReaderT Html Identity a -> ReaderT Html Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (RWST
  (Maybe (Env, FileEnv), FlexForm, [Text])
  Enctype
  Ints
  Handler
  [[([Text], Widget)]]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([Text], [[Widget]])
forall {a} {b}.
RWST
  (Maybe (Env, FileEnv), FlexForm, [Text])
  Enctype
  Ints
  Handler
  [[([a], b)]]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([a], [[b]])
tupleSequence (RWST
   (Maybe (Env, FileEnv), FlexForm, [Text])
   Enctype
   Ints
   Handler
   [[([Text], Widget)]]
 -> RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], [[Widget]]))
-> ([[RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget)]]
    -> RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         [[([Text], Widget)]])
-> [[RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget)]]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([Text], [[Widget]])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([RWST
    (Maybe (Env, FileEnv), FlexForm, [Text])
    Enctype
    Ints
    Handler
    ([Text], Widget)]
 -> RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      [([Text], Widget)])
-> [[RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget)]]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     [[([Text], Widget)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM [RWST
   (Maybe (Env, FileEnv), FlexForm, [Text])
   Enctype
   Ints
   Handler
   ([Text], Widget)]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     [([Text], Widget)]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence) (ReaderT
   Html
   Identity
   [[RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget)]]
 -> ReaderT
      Html
      Identity
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], [[Widget]])))
-> ([[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]]
    -> ReaderT
         Html
         Identity
         [[RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget)]])
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> ReaderT
     Html
     Identity
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], [[Widget]]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]
 -> ReaderT
      Html
      Identity
      [RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget)])
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> ReaderT
     Html
     Identity
     [[RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM [Reader
   Html
   (RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget))]
-> ReaderT
     Html
     Identity
     [RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget)]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence)
  where tupleSequence :: RWST
  (Maybe (Env, FileEnv), FlexForm, [Text])
  Enctype
  Ints
  Handler
  [[([a], b)]]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([a], [[b]])
tupleSequence = ([[([a], b)]] -> ([a], [[b]]))
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     [[([a], b)]]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([a], [[b]])
forall a b.
(a -> b)
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text]) Enctype Ints Handler a
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text]) Enctype Ints Handler b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([([a], [b])] -> ([a], [[b]])
forall a b. [([a], b)] -> ([a], [b])
joinAndPart ([([a], [b])] -> ([a], [[b]]))
-> ([[([a], b)]] -> [([a], [b])]) -> [[([a], b)]] -> ([a], [[b]])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([([a], b)] -> ([a], [b])) -> [[([a], b)]] -> [([a], [b])]
forall a b. (a -> b) -> [a] -> [b]
map [([a], b)] -> ([a], [b])
forall a b. [([a], b)] -> ([a], [b])
joinAndPart)


{- |
like `formifyComponents`, but takes a simple list of `FieldInfo` values.
The sub-renders will also be returned as a flat list without any additional structure.
-}
formifyComponentsFlat :: Formify a => Maybe a -> [FieldInfo] -> Rendered [Widget]
formifyComponentsFlat :: forall a. Formify a => Maybe a -> [FieldInfo] -> Rendered [Widget]
formifyComponentsFlat Maybe a
ma = ([[Rendered Widget]]
 -> ReaderT
      Html
      Identity
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], [Widget])))
-> Maybe a
-> [[FieldInfo]]
-> ReaderT
     Html
     Identity
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], [Widget]))
forall a b.
Formify a =>
([[Rendered Widget]] -> b) -> Maybe a -> [[FieldInfo]] -> b
checkAndApply (([RWST
    (Maybe (Env, FileEnv), FlexForm, [Text])
    Enctype
    Ints
    Handler
    ([Text], Widget)]
 -> RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], [Widget]))
-> ReaderT
     Html
     Identity
     [RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget)]
-> ReaderT
     Html
     Identity
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], [Widget]))
forall a b.
(a -> b) -> ReaderT Html Identity a -> ReaderT Html Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (RWST
  (Maybe (Env, FileEnv), FlexForm, [Text])
  Enctype
  Ints
  Handler
  [([Text], Widget)]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([Text], [Widget])
forall {a} {b}.
RWST
  (Maybe (Env, FileEnv), FlexForm, [Text])
  Enctype
  Ints
  Handler
  [([a], b)]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([a], [b])
tupleSequence (RWST
   (Maybe (Env, FileEnv), FlexForm, [Text])
   Enctype
   Ints
   Handler
   [([Text], Widget)]
 -> RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], [Widget]))
-> ([RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget)]
    -> RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         [([Text], Widget)])
-> [RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget)]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([Text], [Widget])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RWST
   (Maybe (Env, FileEnv), FlexForm, [Text])
   Enctype
   Ints
   Handler
   ([Text], Widget)]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     [([Text], Widget)]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence) (ReaderT
   Html
   Identity
   [RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget)]
 -> ReaderT
      Html
      Identity
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], [Widget])))
-> ([[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]]
    -> ReaderT
         Html
         Identity
         [RWST
            (Maybe (Env, FileEnv), FlexForm, [Text])
            Enctype
            Ints
            Handler
            ([Text], Widget)])
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> ReaderT
     Html
     Identity
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], [Widget]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Reader
   Html
   (RWST
      (Maybe (Env, FileEnv), FlexForm, [Text])
      Enctype
      Ints
      Handler
      ([Text], Widget))]
-> ReaderT
     Html
     Identity
     [RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget)]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ([Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]
 -> ReaderT
      Html
      Identity
      [RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget)])
-> ([[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]]
    -> [Reader
          Html
          (RWST
             (Maybe (Env, FileEnv), FlexForm, [Text])
             Enctype
             Ints
             Handler
             ([Text], Widget))])
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> ReaderT
     Html
     Identity
     [RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> [Reader
      Html
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat) Maybe a
ma ([[FieldInfo]]
 -> ReaderT
      Html
      Identity
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], [Widget])))
-> ([FieldInfo] -> [[FieldInfo]])
-> [FieldInfo]
-> ReaderT
     Html
     Identity
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], [Widget]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([FieldInfo] -> [[FieldInfo]] -> [[FieldInfo]]
forall a. a -> [a] -> [a]
:[])
  where tupleSequence :: RWST
  (Maybe (Env, FileEnv), FlexForm, [Text])
  Enctype
  Ints
  Handler
  [([a], b)]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([a], [b])
tupleSequence = ([([a], b)] -> ([a], [b]))
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     [([a], b)]
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text])
     Enctype
     Ints
     Handler
     ([a], [b])
forall a b.
(a -> b)
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text]) Enctype Ints Handler a
-> RWST
     (Maybe (Env, FileEnv), FlexForm, [Text]) Enctype Ints Handler b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [([a], b)] -> ([a], [b])
forall a b. [([a], b)] -> ([a], [b])
joinAndPart


joinAndPart :: [([a],b)] -> ([a],[b])
joinAndPart :: forall a b. [([a], b)] -> ([a], [b])
joinAndPart = ([[a]] -> [a]) -> ([[a]], [b]) -> ([a], [b])
forall a a' b. (a -> a') -> (a, b) -> (a', b)
first [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (([[a]], [b]) -> ([a], [b]))
-> ([([a], b)] -> ([[a]], [b])) -> [([a], b)] -> ([a], [b])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [([a], b)] -> ([[a]], [b])
forall a b. [(a, b)] -> ([a], [b])
unzip


checkAndApply
  :: Formify a
  => ([[Rendered Widget]] -> b)
  -> Maybe a
  -> [[FieldInfo]]
  -> b
checkAndApply :: forall a b.
Formify a =>
([[Rendered Widget]] -> b) -> Maybe a -> [[FieldInfo]] -> b
checkAndApply [[Rendered Widget]] -> b
toOutput Maybe a
ma [[FieldInfo]]
xs = case [[FieldInfo]]
rest of
    ([]:[[FieldInfo]]
ns)
      | [[FieldInfo]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[FieldInfo]]
ns   -> [[Rendered Widget]] -> b
toOutput [[Rendered Widget]]
[[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
renders
    [[FieldInfo]]
_ -> String -> b
forall a. HasCallStack => String -> a
error (String -> b) -> String -> b
forall a b. (a -> b) -> a -> b
$
      String
"The form generation did not use up all supplied FieldSettings values. " String -> ShowS
forall a. [a] -> [a] -> [a]
++
      String
"Confirm your field type make sense with the amount of given FieldInfo values."
  where
    ([[FieldInfo]]
rest, [[Rendered Widget]]
renders) = Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Formify a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation Maybe a
ma [[FieldInfo]]
xs


renderNextField
  :: (FieldInfo ->
       ( FieldSettings FlexForm
       , Bool
       , FieldSettings FlexForm -> Maybe a -> AForm Handler a
       )
     )
  -> Maybe a
  -> [[FieldInfo]]
  -> ([[FieldInfo]], [[Rendered Widget]])
renderNextField :: forall a.
(FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe a -> AForm Handler a))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextField FieldInfo
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm -> Maybe a -> AForm Handler a)
_ Maybe a
_ [] = String
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall a. HasCallStack => String -> a
error String
"Ran out of FieldInfo values before finishing the form!"
renderNextField FieldInfo
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm -> Maybe a -> AForm Handler a)
h Maybe a
ma ((FieldInfo
x : [FieldInfo]
xs) : [[FieldInfo]]
xss) =
  let
    (FieldSettings FlexForm
lab, Bool
newId, FieldSettings FlexForm -> Maybe a -> AForm Handler a
g) = FieldInfo
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm -> Maybe a -> AForm Handler a)
h FieldInfo
x
  in
    ([FieldInfo]
xs[FieldInfo] -> [[FieldInfo]] -> [[FieldInfo]]
forall a. a -> [a] -> [a]
:[[FieldInfo]]
xss, [[Bool
-> (FieldSettings FlexForm -> AForm Handler a)
-> FieldSettings FlexForm
-> Rendered Widget
forall a.
Bool
-> (FieldSettings FlexForm -> AForm Handler a)
-> FieldSettings FlexForm
-> Rendered Widget
renderForm Bool
newId (FieldSettings FlexForm -> Maybe a -> AForm Handler a
`g` Maybe a
ma) FieldSettings FlexForm
lab]])
renderNextField FieldInfo
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm -> Maybe a -> AForm Handler a)
_ Maybe a
_ [[FieldInfo]]
_ = String
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall a. HasCallStack => String -> a
error String
"Incorrect FieldInfo for a field or single/multi choice!"

{- |
Premade `formifyImplementation` for types with `BaseForm` instances.
Use within manual instances of `Formify`.
-}
formifyInstanceBasicField
    :: BaseForm a
    => Maybe a
    -> [[FieldInfo]]
    -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField :: forall a.
BaseForm a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceBasicField = (FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe a -> AForm Handler a))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
(FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe a -> AForm Handler a))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextField
  (\case
      Single FieldSettings FlexForm
fs -> (FieldSettings FlexForm
fs, Bool
True, Field Handler a
-> FieldSettings FlexForm -> Maybe a -> AForm Handler a
forall site (m :: * -> *) a.
(RenderMessage site FormMessage, HandlerSite m ~ site,
 MonadHandler m) =>
Field m a -> FieldSettings site -> Maybe a -> AForm m a
areq Field Handler a
forall a. BaseForm a => Field Handler a
baseForm)
      InternalListElem FieldSettings FlexForm
fs -> (FieldSettings FlexForm
fs, Bool
False, Field Handler a
-> FieldSettings FlexForm -> Maybe a -> AForm Handler a
forall site (m :: * -> *) a.
(RenderMessage site FormMessage, HandlerSite m ~ site,
 MonadHandler m) =>
Field m a -> FieldSettings site -> Maybe a -> AForm m a
areq Field Handler a
forall a. BaseForm a => Field Handler a
baseForm)
      FieldInfo
_ -> String
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm -> Maybe a -> AForm Handler a)
forall a. HasCallStack => String -> a
error String
"Incorrect FieldInfo for a basic field. Use 'single'!"
  )

{- |
Same as `formifyInstanceBasicField`, but for optional fields with `Maybe` wrapping.
-}
formifyInstanceOptionalField
    :: BaseForm a
    => Maybe (Maybe a)
    -> [[FieldInfo]]
    -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceOptionalField :: forall a.
BaseForm a =>
Maybe (Maybe a)
-> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceOptionalField = (FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm
     -> Maybe (Maybe a) -> AForm Handler (Maybe a)))
-> Maybe (Maybe a)
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
forall a.
(FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe a -> AForm Handler a))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextField
  (\case
      Single FieldSettings FlexForm
fs -> (FieldSettings FlexForm
fs, Bool
True, Field Handler a
-> FieldSettings (HandlerSite Handler)
-> Maybe (Maybe a)
-> AForm Handler (Maybe a)
forall (m :: * -> *) a.
MonadHandler m =>
Field m a
-> FieldSettings (HandlerSite m)
-> Maybe (Maybe a)
-> AForm m (Maybe a)
aopt Field Handler a
forall a. BaseForm a => Field Handler a
baseForm)
      InternalListElem FieldSettings FlexForm
fs -> (FieldSettings FlexForm
fs, Bool
False, Field Handler a
-> FieldSettings (HandlerSite Handler)
-> Maybe (Maybe a)
-> AForm Handler (Maybe a)
forall (m :: * -> *) a.
MonadHandler m =>
Field m a
-> FieldSettings (HandlerSite m)
-> Maybe (Maybe a)
-> AForm m (Maybe a)
aopt Field Handler a
forall a. BaseForm a => Field Handler a
baseForm)
      FieldInfo
_ -> String
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm
    -> Maybe (Maybe a) -> AForm Handler (Maybe a))
forall a. HasCallStack => String -> a
error String
"Incorrect FieldInfo for an optional basic field. Use 'single'!"
  )


formifyInstanceList
    :: (Formify a)
    => Maybe [a]
    -> [[FieldInfo]]
    -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceList :: forall a.
Formify a =>
Maybe [a] -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceList Maybe [a]
_ [] = String
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall a. HasCallStack => String -> a
error String
"Ran out of FieldInfo values before finishing the form!"
formifyInstanceList Maybe [a]
_ ((List Alignment
_ [] : [FieldInfo]
_) : [[FieldInfo]]
_) = String
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall a. HasCallStack => String -> a
error String
"List used without supplying any FieldInfo values!"
formifyInstanceList Maybe [a]
mas ((List Alignment
align (FieldSettings FlexForm
f:[FieldSettings FlexForm]
fs) : [FieldInfo]
xs) : [[FieldInfo]]
xss) =
    ( [FieldInfo]
xs[FieldInfo] -> [[FieldInfo]] -> [[FieldInfo]]
forall a. a -> [a] -> [a]
:[[FieldInfo]]
xss
    , case Alignment
align of
        Alignment
Horizontal -> [[[Rendered Widget]] -> [Rendered Widget]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Rendered Widget]] -> [Rendered Widget])
-> [[Rendered Widget]] -> [Rendered Widget]
forall a b. (a -> b) -> a -> b
$ [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
firstRender [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall a. [a] -> [a] -> [a]
++ [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
followingRenders]
        Alignment
Vertical   -> [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
firstRender [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall a. [a] -> [a] -> [a]
++ [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
followingRenders
    )
  where
    defaults :: [Maybe a]
defaults = case Maybe [a]
mas of
      Maybe [a]
Nothing -> Maybe a -> [Maybe a]
forall a. a -> [a]
repeat Maybe a
forall a. Maybe a
Nothing
      Just [a]
ds
        | [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
ds Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [FieldSettings FlexForm] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [FieldSettings FlexForm]
fs Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1
          -> String -> [Maybe a]
forall a. HasCallStack => String -> a
error (String -> [Maybe a]) -> String -> [Maybe a]
forall a b. (a -> b) -> a -> b
$ String
"The default value contains too many/few individual values. " String -> ShowS
forall a. [a] -> [a] -> [a]
++
                     String
"It does not match the amount of FieldInfo supplied."
        | Bool
otherwise
          -> Maybe [a] -> [Maybe a]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => Maybe (m a) -> m (Maybe a)
sequence Maybe [a]
mas

    headError :: [a] -> a
headError [] = String -> a
forall a. HasCallStack => String -> a
error String
"Defaults should never be empty here!"
    headError (a
x:[a]
_) = a
x

    firstRender :: [[Rendered Widget]]
firstRender = ([[FieldInfo]], [[Rendered Widget]]) -> [[Rendered Widget]]
forall a b. (a, b) -> b
snd (([[FieldInfo]], [[Rendered Widget]]) -> [[Rendered Widget]])
-> ([[FieldInfo]], [[Rendered Widget]]) -> [[Rendered Widget]]
forall a b. (a -> b) -> a -> b
$ Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Formify a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation ([Maybe a] -> Maybe a
forall {a}. [a] -> a
headError [Maybe a]
defaults) [[FieldSettings FlexForm -> FieldInfo
single FieldSettings FlexForm
f]]
    renderRest :: Maybe a
-> FieldSettings FlexForm -> ([[FieldInfo]], [[Rendered Widget]])
renderRest Maybe a
def FieldSettings FlexForm
fSettings = Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Formify a =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyImplementation Maybe a
def [[FieldSettings FlexForm -> FieldInfo
InternalListElem FieldSettings FlexForm
fSettings]]
    followingRenders :: [[Reader
    Html
    (RWST
       (Maybe (Env, FileEnv), FlexForm, [Text])
       Enctype
       Ints
       Handler
       ([Text], Widget))]]
followingRenders = [[[Reader
     Html
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget))]]]
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [([[FieldInfo]],
 [[Reader
     Html
     (RWST
        (Maybe (Env, FileEnv), FlexForm, [Text])
        Enctype
        Ints
        Handler
        ([Text], Widget))]])
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall a b. (a, b) -> b
snd (([[FieldInfo]],
  [[Reader
      Html
      (RWST
         (Maybe (Env, FileEnv), FlexForm, [Text])
         Enctype
         Ints
         Handler
         ([Text], Widget))]])
 -> [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
-> [[Reader
       Html
       (RWST
          (Maybe (Env, FileEnv), FlexForm, [Text])
          Enctype
          Ints
          Handler
          ([Text], Widget))]]
forall a b. (a -> b) -> a -> b
$ Maybe a
-> FieldSettings FlexForm
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall {a}.
Formify a =>
Maybe a
-> FieldSettings FlexForm
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
renderRest Maybe a
d FieldSettings FlexForm
fSet | (Maybe a
d,FieldSettings FlexForm
fSet) <- [Maybe a]
-> [FieldSettings FlexForm] -> [(Maybe a, FieldSettings FlexForm)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Int -> [Maybe a] -> [Maybe a]
forall a. Int -> [a] -> [a]
drop Int
1 [Maybe a]
defaults) [FieldSettings FlexForm]
fs]

formifyInstanceList Maybe [a]
_ [[FieldInfo]]
_ = String
-> ([[FieldInfo]],
    [[Reader
        Html
        (RWST
           (Maybe (Env, FileEnv), FlexForm, [Text])
           Enctype
           Ints
           Handler
           ([Text], Widget))]])
forall a. HasCallStack => String -> a
error String
"Incorrect FieldInfo for a list of fields! Use one of the list builders."



{- |
Premade `formifyImplementation` for "single choice" forms of enum types.
Use within manual instances of `Formify`.
-}
formifyInstanceSingleChoice
    :: (Bounded a, Enum a, Eq a)
    => Maybe a
    -> [[FieldInfo]]
    -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceSingleChoice :: forall a.
(Bounded a, Enum a, Eq a) =>
Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceSingleChoice = ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Eq a =>
([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextSingleChoiceField [SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
forall a.
(Bounded a, Enum a) =>
[SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
zipWithEnum

renderNextSingleChoiceField
    :: Eq a
    => ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
    -> Maybe a
    -> [[FieldInfo]]
    -> ([[FieldInfo]], [[Rendered Widget]])
renderNextSingleChoiceField :: forall a.
Eq a =>
([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextSingleChoiceField [SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
pairsWith =
  (FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe a -> AForm Handler a))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
forall a.
(FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe a -> AForm Handler a))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextField
  (\case
      ChoicesDropdown FieldSettings FlexForm
fs [SomeMessage FlexForm]
opts -> ( FieldSettings FlexForm
fs
                                 , Bool
True
                                 , Field Handler a
-> FieldSettings FlexForm -> Maybe a -> AForm Handler a
forall site (m :: * -> *) a.
(RenderMessage site FormMessage, HandlerSite m ~ site,
 MonadHandler m) =>
Field m a -> FieldSettings site -> Maybe a -> AForm m a
areq (Field Handler a
 -> FieldSettings FlexForm -> Maybe a -> AForm Handler a)
-> Field Handler a
-> FieldSettings FlexForm
-> Maybe a
-> AForm Handler a
forall a b. (a -> b) -> a -> b
$ HandlerFor FlexForm (OptionList a) -> Field Handler a
forall a site.
(Eq a, RenderMessage site FormMessage) =>
HandlerFor site (OptionList a) -> Field (HandlerFor site) a
selectField (HandlerFor FlexForm (OptionList a) -> Field Handler a)
-> HandlerFor FlexForm (OptionList a) -> Field Handler a
forall a b. (a -> b) -> a -> b
$ [SomeMessage FlexForm] -> HandlerFor FlexForm (OptionList a)
withOptions [SomeMessage FlexForm]
opts
                                 )
      ChoicesButtons Alignment
align FieldSettings FlexForm
fs [SomeMessage FlexForm]
opts -> ( FieldSettings FlexForm
fs
                                      , Bool
True
                                      , Field Handler a
-> FieldSettings FlexForm -> Maybe a -> AForm Handler a
forall site (m :: * -> *) a.
(RenderMessage site FormMessage, HandlerSite m ~ site,
 MonadHandler m) =>
Field m a -> FieldSettings site -> Maybe a -> AForm m a
areq (Field Handler a
 -> FieldSettings FlexForm -> Maybe a -> AForm Handler a)
-> Field Handler a
-> FieldSettings FlexForm
-> Maybe a
-> AForm Handler a
forall a b. (a -> b) -> a -> b
$
                                          case Alignment
align of
                                            Alignment
Vertical -> HandlerFor FlexForm (OptionList a) -> Field Handler a
forall a site.
(Eq a, RenderMessage site FormMessage) =>
HandlerFor site (OptionList a) -> Field (HandlerFor site) a
radioField
                                            Alignment
Horizontal -> HandlerFor FlexForm (OptionList a) -> Field Handler a
forall a. Eq a => Handler (OptionList a) -> Field Handler a
horizontalRadioField
                                          (HandlerFor FlexForm (OptionList a) -> Field Handler a)
-> HandlerFor FlexForm (OptionList a) -> Field Handler a
forall a b. (a -> b) -> a -> b
$ [SomeMessage FlexForm] -> HandlerFor FlexForm (OptionList a)
withOptions [SomeMessage FlexForm]
opts
                                      )
      FieldInfo
_ -> String
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm -> Maybe a -> AForm Handler a)
forall a. HasCallStack => String -> a
error String
"Incorrect FieldInfo for a single choice field! Use one of the 'buttons' or 'dropdown' functions."
  )
  where withOptions :: [SomeMessage FlexForm] -> HandlerFor FlexForm (OptionList a)
withOptions = [(SomeMessage FlexForm, a)] -> HandlerFor FlexForm (OptionList a)
forall (m :: * -> *) msg a.
(MonadHandler m, RenderMessage (HandlerSite m) msg) =>
[(msg, a)] -> m (OptionList a)
optionsPairs ([(SomeMessage FlexForm, a)] -> HandlerFor FlexForm (OptionList a))
-> ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> [SomeMessage FlexForm]
-> HandlerFor FlexForm (OptionList a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
pairsWith

renderNextMultipleChoiceField
    :: Eq a
    => ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
    -> Maybe [a]
    -> [[FieldInfo]]
    -> ([[FieldInfo]], [[Rendered Widget]])
renderNextMultipleChoiceField :: forall a.
Eq a =>
([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe [a]
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
renderNextMultipleChoiceField [SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
pairsWith =
  (FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe [a] -> AForm Handler [a]))
-> Maybe [a]
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
forall a.
(FieldInfo
 -> (FieldSettings FlexForm, Bool,
     FieldSettings FlexForm -> Maybe a -> AForm Handler a))
-> Maybe a -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
renderNextField
  (\case
      ChoicesDropdown FieldSettings FlexForm
fs [SomeMessage FlexForm]
opts -> ( FieldSettings FlexForm
fs
                                 , Bool
True
                                 , Field Handler [a]
-> FieldSettings FlexForm -> Maybe [a] -> AForm Handler [a]
forall site (m :: * -> *) a.
(RenderMessage site FormMessage, HandlerSite m ~ site,
 MonadHandler m) =>
Field m a -> FieldSettings site -> Maybe a -> AForm m a
areq (Field Handler [a]
 -> FieldSettings FlexForm -> Maybe [a] -> AForm Handler [a])
-> Field Handler [a]
-> FieldSettings FlexForm
-> Maybe [a]
-> AForm Handler [a]
forall a b. (a -> b) -> a -> b
$ HandlerFor FlexForm (OptionList a) -> Field Handler [a]
forall a site.
Eq a =>
HandlerFor site (OptionList a) -> Field (HandlerFor site) [a]
multiSelectField (HandlerFor FlexForm (OptionList a) -> Field Handler [a])
-> HandlerFor FlexForm (OptionList a) -> Field Handler [a]
forall a b. (a -> b) -> a -> b
$ [SomeMessage FlexForm] -> HandlerFor FlexForm (OptionList a)
withOptions [SomeMessage FlexForm]
opts
                                 )
      ChoicesButtons Alignment
align FieldSettings FlexForm
fs [SomeMessage FlexForm]
opts -> ( FieldSettings FlexForm
fs
                                      , Bool
True
                                      , Field Handler [a]
-> FieldSettings FlexForm -> Maybe [a] -> AForm Handler [a]
forall site (m :: * -> *) a.
(RenderMessage site FormMessage, HandlerSite m ~ site,
 MonadHandler m) =>
Field m a -> FieldSettings site -> Maybe a -> AForm m a
areq (Field Handler [a]
 -> FieldSettings FlexForm -> Maybe [a] -> AForm Handler [a])
-> Field Handler [a]
-> FieldSettings FlexForm
-> Maybe [a]
-> AForm Handler [a]
forall a b. (a -> b) -> a -> b
$
                                          case Alignment
align of
                                            Alignment
Vertical   -> Bool -> HandlerFor FlexForm (OptionList a) -> Field Handler [a]
forall a.
Eq a =>
Bool -> Handler (OptionList a) -> Field Handler [a]
checkboxField Bool
True
                                            Alignment
Horizontal -> Bool -> HandlerFor FlexForm (OptionList a) -> Field Handler [a]
forall a.
Eq a =>
Bool -> Handler (OptionList a) -> Field Handler [a]
checkboxField Bool
False
                                          (HandlerFor FlexForm (OptionList a) -> Field Handler [a])
-> HandlerFor FlexForm (OptionList a) -> Field Handler [a]
forall a b. (a -> b) -> a -> b
$ [SomeMessage FlexForm] -> HandlerFor FlexForm (OptionList a)
withOptions [SomeMessage FlexForm]
opts
                                      )
      FieldInfo
_ -> String
-> (FieldSettings FlexForm, Bool,
    FieldSettings FlexForm -> Maybe [a] -> AForm Handler [a])
forall a. HasCallStack => String -> a
error String
"Incorrect FieldInfo for a multiple choice field! Use one of the 'buttons' or 'dropdown' functions."
  )
  where withOptions :: [SomeMessage FlexForm] -> HandlerFor FlexForm (OptionList a)
withOptions = [(SomeMessage FlexForm, a)] -> HandlerFor FlexForm (OptionList a)
forall (m :: * -> *) msg a.
(MonadHandler m, RenderMessage (HandlerSite m) msg) =>
[(msg, a)] -> m (OptionList a)
optionsPairs ([(SomeMessage FlexForm, a)] -> HandlerFor FlexForm (OptionList a))
-> ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> [SomeMessage FlexForm]
-> HandlerFor FlexForm (OptionList a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
pairsWith



-- | Same as `formifyInstanceSingleChoice`, but for multiple choice.
formifyInstanceMultiChoice
    :: (Bounded a, Enum a, Eq a)
    => Maybe [a]
    -> [[FieldInfo]]
    -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceMultiChoice :: forall a.
(Bounded a, Enum a, Eq a) =>
Maybe [a] -> [[FieldInfo]] -> ([[FieldInfo]], [[Rendered Widget]])
formifyInstanceMultiChoice = ([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe [a]
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
forall a.
Eq a =>
([SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)])
-> Maybe [a]
-> [[FieldInfo]]
-> ([[FieldInfo]], [[Rendered Widget]])
renderNextMultipleChoiceField [SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
forall a.
(Bounded a, Enum a) =>
[SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
zipWithEnum



zipWithEnum :: forall a. (Bounded a, Enum a) => [SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
zipWithEnum :: forall a.
(Bounded a, Enum a) =>
[SomeMessage FlexForm] -> [(SomeMessage FlexForm, a)]
zipWithEnum [SomeMessage FlexForm]
labels
  | [SomeMessage FlexForm] -> [a] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [SomeMessage FlexForm]
labels [a]
options = [SomeMessage FlexForm] -> [a] -> [(SomeMessage FlexForm, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [SomeMessage FlexForm]
labels [a]
options
  | Bool
otherwise = String -> [(SomeMessage FlexForm, a)]
forall a. HasCallStack => String -> a
error String
"Labels list and options list are of different lengths in an Enum choice form."
  where options :: [a]
options = [a
forall a. Bounded a => a
minBound .. a
forall a. Bounded a => a
maxBound :: a]






{- |
Same as `buttons`, but using an explicit enum type.
Use this with custom enum types to automatically create labels
for all constructors according to the given showing scheme.
-}
buttonsEnum
  :: (Bounded a, Enum a)
  => Alignment
  -> FieldSettings FlexForm      -- ^ FieldSettings for option input
  -> (a -> SomeMessage FlexForm) -- ^ Function from enum type values to labels.
  -> FieldInfo
buttonsEnum :: forall a.
(Bounded a, Enum a) =>
Alignment
-> FieldSettings FlexForm
-> (a -> SomeMessage FlexForm)
-> FieldInfo
buttonsEnum Alignment
align FieldSettings FlexForm
t a -> SomeMessage FlexForm
f = Alignment
-> FieldSettings FlexForm -> [SomeMessage FlexForm] -> FieldInfo
ChoicesButtons Alignment
align FieldSettings FlexForm
t ([SomeMessage FlexForm] -> FieldInfo)
-> [SomeMessage FlexForm] -> FieldInfo
forall a b. (a -> b) -> a -> b
$ (a -> SomeMessage FlexForm) -> [a] -> [SomeMessage FlexForm]
forall a b. (a -> b) -> [a] -> [b]
map a -> SomeMessage FlexForm
f [a
forall a. Bounded a => a
minBound .. a
forall a. Bounded a => a
maxBound]



{- |
Create FieldInfo for a button field.
Will turn into either radio buttons or checkboxes
depending on the form type.
Use with SingleChoiceSelection or MultipleChoiceSelection.
__Usage with a custom enum type is not recommended due to error proneness.__
-}
buttons
  :: Alignment
  -> FieldSettings FlexForm -- ^ FieldSettings for option input
  -> [SomeMessage FlexForm] -- ^ Option labels
  -> FieldInfo
buttons :: Alignment
-> FieldSettings FlexForm -> [SomeMessage FlexForm] -> FieldInfo
buttons = Alignment
-> FieldSettings FlexForm -> [SomeMessage FlexForm] -> FieldInfo
ChoicesButtons



{- |
Same as `dropdown`, but using an explicit enum type.
Use this with custom enum types to automatically create labels
for all constructors according to the given showing scheme.
-}
dropdownEnum
  :: (Bounded a, Enum a)
  => FieldSettings FlexForm      -- ^ FieldSettings for select input
  -> (a -> SomeMessage FlexForm) -- ^ Function from enum type values to labels.
  -> FieldInfo
dropdownEnum :: forall a.
(Bounded a, Enum a) =>
FieldSettings FlexForm -> (a -> SomeMessage FlexForm) -> FieldInfo
dropdownEnum FieldSettings FlexForm
t a -> SomeMessage FlexForm
f = FieldSettings FlexForm -> [SomeMessage FlexForm] -> FieldInfo
ChoicesDropdown FieldSettings FlexForm
t ([SomeMessage FlexForm] -> FieldInfo)
-> [SomeMessage FlexForm] -> FieldInfo
forall a b. (a -> b) -> a -> b
$ (a -> SomeMessage FlexForm) -> [a] -> [SomeMessage FlexForm]
forall a b. (a -> b) -> [a] -> [b]
map a -> SomeMessage FlexForm
f [a
forall a. Bounded a => a
minBound .. a
forall a. Bounded a => a
maxBound]



{- |
Create FieldInfo for a dropdown menu field.
Will turn into either single or multiple selection field
depending on the form type.
Use with SingleChoiceSelection or MultipleChoiceSelection.
__Usage with a custom enum types is not recommended due to error proneness.__
-}
dropdown
  :: FieldSettings FlexForm  -- ^ FieldSettings for select input
  -> [SomeMessage FlexForm]  -- ^ Option labels
  -> FieldInfo
dropdown :: FieldSettings FlexForm -> [SomeMessage FlexForm] -> FieldInfo
dropdown = FieldSettings FlexForm -> [SomeMessage FlexForm] -> FieldInfo
ChoicesDropdown



{- |
Create FieldInfo for a number of fields.
Their result will be handled as a list of values.
-}
list
  :: Alignment
  -> [FieldSettings FlexForm] -- ^ FieldSettings of individual fields
  -> FieldInfo
list :: Alignment -> [FieldSettings FlexForm] -> FieldInfo
list = Alignment -> [FieldSettings FlexForm] -> FieldInfo
List



{- |
Same as `list`, but without using any field labels.
Attributes and CSS classes for each field cannot be set with this function.
Instead, all fields share the given list of attributes.
Use `list` if individual configuration is required.
-}
listWithoutLabels
  :: Alignment
  -> Int           -- ^ Amount of fields
  -> [(Text,Text)] -- ^ List of attribute and value pairs (attribute "class" for classes)
  -> FieldInfo
listWithoutLabels :: Alignment -> Int -> [(Text, Text)] -> FieldInfo
listWithoutLabels Alignment
align Int
amount [(Text, Text)]
attrs = Alignment -> [FieldSettings FlexForm] -> FieldInfo
List Alignment
align ([FieldSettings FlexForm] -> FieldInfo)
-> [FieldSettings FlexForm] -> FieldInfo
forall a b. (a -> b) -> a -> b
$ Int -> FieldSettings FlexForm -> [FieldSettings FlexForm]
forall a. Int -> a -> [a]
replicate Int
amount (FieldSettings FlexForm -> [FieldSettings FlexForm])
-> FieldSettings FlexForm -> [FieldSettings FlexForm]
forall a b. (a -> b) -> a -> b
$ FieldSettings FlexForm
"" {fsAttrs = attrs}



-- | Create FieldInfo for a standalone field.
single :: FieldSettings FlexForm -> FieldInfo
single :: FieldSettings FlexForm -> FieldInfo
single = FieldSettings FlexForm -> FieldInfo
Single