{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module IHP.View.Form.Fields where
import IHP.HSX.ConvertibleStrings ()
import IHP.HSX.Markup (Markup, ToHtml(..))
import IHP.ModelSupport (InputValue, getModelName, inputValue)
import IHP.Prelude
import IHP.ValidationSupport
import IHP.View.Classes ()
import IHP.View.Types
textField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
textField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field = FormField
{ fieldType :: InputType
fieldType = InputType
TextInput
, fieldName :: Text
fieldName = ?formContext::FormContext model
FormContext model
?formContext.fieldNamePrefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
fieldName
, fieldLabel :: Text
fieldLabel = Text -> Text
fieldNameToFieldLabel (String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
fieldName)
, fieldValue :: Text
fieldValue = value -> Text
forall a. InputValue a => a -> Text
inputValue ((forall {k} (x :: k) r a. HasField x r a => r -> a
forall (x :: Symbol) r a. HasField x r a => r -> a
getField @fieldName model
model) :: value)
, fieldInputId :: Text
fieldInputId = Text -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (Text -> Text
lcfirst (forall model. KnownSymbol (GetModelName model) => Text
getModelName @model) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
fieldName)
, validatorResult :: Maybe Violation
validatorResult = Proxy fieldName -> model -> Maybe Violation
forall (field :: Symbol) model.
(KnownSymbol field, HasField "meta" model MetaBag) =>
Proxy field -> model -> Maybe Violation
getValidationViolation Proxy fieldName
field model
model
, fieldClass :: Text
fieldClass = Text
""
, labelClass :: Text
labelClass = Text
""
, disabled :: Bool
disabled = Bool
False
, disableLabel :: Bool
disableLabel = Bool
False
, disableGroup :: Bool
disableGroup = Bool
False
, disableValidationResult :: Bool
disableValidationResult = Bool
False
, additionalAttributes :: [(Text, Text)]
additionalAttributes = []
, cssFramework :: CSSFramework
cssFramework = ?formContext::FormContext model
FormContext model
?formContext.cssFramework
, helpText :: Text
helpText = Text
""
, placeholder :: Text
placeholder = Text
""
, required :: Bool
required = Bool
False
, autofocus :: Bool
autofocus = Bool
False
}
where
fieldName :: String
fieldName = Proxy fieldName -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal Proxy fieldName
field
FormContext { model
model :: model
model :: forall model. FormContext model -> model
model } = ?formContext::FormContext model
FormContext model
?formContext
{-# INLINE textField #-}
numberField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
numberField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
numberField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = NumberInput }
{-# INLINE numberField #-}
urlField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
urlField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
urlField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = UrlInput }
{-# INLINE urlField #-}
textareaField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
textareaField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textareaField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = TextareaInput }
{-# INLINE textareaField #-}
colorField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
colorField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
colorField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = ColorInput }
{-# INLINE colorField #-}
emailField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, KnownSymbol (GetModelName model)
, InputValue value
) => Proxy fieldName -> FormField
emailField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
KnownSymbol (GetModelName model), InputValue value) =>
Proxy fieldName -> FormField
emailField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = EmailInput }
{-# INLINE emailField #-}
dateField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
dateField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
dateField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = DateInput }
{-# INLINE dateField #-}
passwordField :: forall fieldName model.
( ?formContext :: FormContext model
, HasField fieldName model Text
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
passwordField :: forall (fieldName :: Symbol) model.
(?formContext::FormContext model, HasField fieldName model Text,
HasField "meta" model MetaBag, KnownSymbol fieldName,
KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
passwordField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = PasswordInput }
{-# INLINE passwordField #-}
dateTimeField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, DateTimeValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
dateTimeField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, DateTimeValue value,
KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
dateTimeField Proxy fieldName
alpha =
(Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
alpha)
{ fieldType = DateTimeInput
, fieldValue = dateTimeValue ((getField @fieldName model) :: value)
}
where
FormContext { model
model :: forall model. FormContext model -> model
model :: model
model } = ?formContext::FormContext model
FormContext model
?formContext
{-# INLINE dateTimeField #-}
class DateTimeValue a where
dateTimeValue :: a -> Text
default dateTimeValue :: FormatTime a => a -> Text
dateTimeValue a
time = String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (TimeLocale -> String -> a -> String
forall t. FormatTime t => TimeLocale -> String -> t -> String
formatTime TimeLocale
defaultTimeLocale String
"%Y-%m-%dT%H:%M" a
time)
instance DateTimeValue UTCTime
instance DateTimeValue LocalTime
instance DateTimeValue a => DateTimeValue (Maybe a) where
dateTimeValue :: Maybe a -> Text
dateTimeValue (Just a
time) = a -> Text
forall a. DateTimeValue a => a -> Text
dateTimeValue a
time
dateTimeValue Maybe a
Nothing = Text
""
hiddenField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
hiddenField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
hiddenField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = HiddenInput, disableLabel = True, disableGroup = True, disableValidationResult = True }
{-# INLINE hiddenField #-}
fileField :: forall fieldName model value.
( ?formContext :: FormContext model
, HasField fieldName model value
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue value
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
fileField :: forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
fileField Proxy fieldName
field = (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field) { fieldType = FileInput }
{-# INLINE fileField #-}
checkboxField :: forall fieldName model.
( ?formContext :: FormContext model
, HasField fieldName model Bool
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> FormField
checkboxField :: forall (fieldName :: Symbol) model.
(?formContext::FormContext model, HasField fieldName model Bool,
HasField "meta" model MetaBag, KnownSymbol fieldName,
KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
checkboxField Proxy fieldName
field = FormField
{ fieldType :: InputType
fieldType = InputType
CheckboxInput
, fieldName :: Text
fieldName = String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
fieldName
, fieldLabel :: Text
fieldLabel = Text -> Text
fieldNameToFieldLabel (String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
fieldName)
, fieldValue :: Text
fieldValue = if forall {k} (x :: k) r a. HasField x r a => r -> a
forall (x :: Symbol) r a. HasField x r a => r -> a
getField @fieldName model
model then Text
"yes" else Text
"no"
, fieldInputId :: Text
fieldInputId = Text -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (Text -> Text
lcfirst (forall model. KnownSymbol (GetModelName model) => Text
getModelName @model) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs String
fieldName)
, validatorResult :: Maybe Violation
validatorResult = Proxy fieldName -> model -> Maybe Violation
forall (field :: Symbol) model.
(KnownSymbol field, HasField "meta" model MetaBag) =>
Proxy field -> model -> Maybe Violation
getValidationViolation Proxy fieldName
field model
model
, fieldClass :: Text
fieldClass = Text
""
, labelClass :: Text
labelClass = Text
""
, disabled :: Bool
disabled = Bool
False
, disableLabel :: Bool
disableLabel = Bool
False
, disableGroup :: Bool
disableGroup = Bool
False
, disableValidationResult :: Bool
disableValidationResult = Bool
False
, additionalAttributes :: [(Text, Text)]
additionalAttributes = []
, cssFramework :: CSSFramework
cssFramework = ?formContext::FormContext model
FormContext model
?formContext.cssFramework
, helpText :: Text
helpText = Text
""
, placeholder :: Text
placeholder = Text
""
, required :: Bool
required = Bool
False
, autofocus :: Bool
autofocus = Bool
False
}
where
fieldName :: String
fieldName = Proxy fieldName -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal Proxy fieldName
field
FormContext { model
model :: forall model. FormContext model -> model
model :: model
model } = ?formContext::FormContext model
FormContext model
?formContext
{-# INLINE checkboxField #-}
instance ToHtml FormField where
{-# INLINE toHtml #-}
toHtml :: FormField -> Markup
toHtml :: FormField -> Markup
toHtml formField :: FormField
formField@(FormField { CSSFramework
cssFramework :: FormField -> CSSFramework
cssFramework :: CSSFramework
cssFramework }) = CSSFramework -> CSSFramework -> FormField -> Markup
styledFormField CSSFramework
cssFramework CSSFramework
cssFramework FormField
formField
instance ToHtml SubmitButton where
{-# INLINE toHtml #-}
toHtml :: SubmitButton -> Markup
toHtml submitButton :: SubmitButton
submitButton@(SubmitButton { CSSFramework
cssFramework :: CSSFramework
cssFramework :: SubmitButton -> CSSFramework
cssFramework }) = CSSFramework -> CSSFramework -> SubmitButton -> Markup
styledSubmitButton CSSFramework
cssFramework CSSFramework
cssFramework SubmitButton
submitButton
validationResult :: forall fieldName model fieldType.
( ?formContext :: FormContext model
, HasField fieldName model fieldType
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, InputValue fieldType
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> Markup
validationResult :: forall (fieldName :: Symbol) model fieldType.
(?formContext::FormContext model,
HasField fieldName model fieldType, HasField "meta" model MetaBag,
KnownSymbol fieldName, InputValue fieldType,
KnownSymbol (GetModelName model)) =>
Proxy fieldName -> Markup
validationResult Proxy fieldName
field = CSSFramework -> CSSFramework -> FormField -> Markup
styledValidationResult CSSFramework
cssFramework CSSFramework
cssFramework (Proxy fieldName -> FormField
forall (fieldName :: Symbol) model value.
(?formContext::FormContext model, HasField fieldName model value,
HasField "meta" model MetaBag, KnownSymbol fieldName,
InputValue value, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> FormField
textField Proxy fieldName
field)
where
result :: Maybe Text
result = Proxy fieldName -> model -> Maybe Text
forall (field :: Symbol) model.
(KnownSymbol field, HasField "meta" model MetaBag) =>
Proxy field -> model -> Maybe Text
getValidationFailure Proxy fieldName
field model
model
model :: model
model = ?formContext::FormContext model
FormContext model
?formContext.model
cssFramework :: CSSFramework
cssFramework = ?formContext::FormContext model
FormContext model
?formContext.cssFramework
validationResultMaybe :: forall fieldName model fieldType.
( ?formContext :: FormContext model
, HasField fieldName model fieldType
, HasField "meta" model MetaBag
, KnownSymbol fieldName
, KnownSymbol (GetModelName model)
) => Proxy fieldName -> Maybe Text
validationResultMaybe :: forall (fieldName :: Symbol) model fieldType.
(?formContext::FormContext model,
HasField fieldName model fieldType, HasField "meta" model MetaBag,
KnownSymbol fieldName, KnownSymbol (GetModelName model)) =>
Proxy fieldName -> Maybe Text
validationResultMaybe Proxy fieldName
field = Proxy fieldName -> model -> Maybe Text
forall (field :: Symbol) model.
(KnownSymbol field, HasField "meta" model MetaBag) =>
Proxy field -> model -> Maybe Text
getValidationFailure Proxy fieldName
field ?formContext::FormContext model
FormContext model
?formContext.model