Cleaned up formlet interface slightly
This commit is contained in:
parent
1236bbeb40
commit
3708445f7a
@ -8,7 +8,6 @@ module Yesod.Contrib.Formable where
|
|||||||
import Text.Hamlet
|
import Text.Hamlet
|
||||||
import Data.Time (Day)
|
import Data.Time (Day)
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Applicative.Error
|
|
||||||
import Web.Routes.Quasi (SinglePiece)
|
import Web.Routes.Quasi (SinglePiece)
|
||||||
import Database.Persist (Persistable)
|
import Database.Persist (Persistable)
|
||||||
import Data.Char (isAlphaNum)
|
import Data.Char (isAlphaNum)
|
||||||
@ -41,7 +40,7 @@ instance Functor FormResult where
|
|||||||
fmap f (FormSuccess a) = FormSuccess $ f a
|
fmap f (FormSuccess a) = FormSuccess $ f a
|
||||||
|
|
||||||
newtype Form url a = Form
|
newtype Form url a = Form
|
||||||
{ runForm :: Env -> Incr (FormResult a, [String] -> Hamlet url)
|
{ runForm :: Env -> Incr (FormResult a, Hamlet url)
|
||||||
}
|
}
|
||||||
type Formlet url a = Maybe a -> Form url a
|
type Formlet url a = Maybe a -> Form url a
|
||||||
|
|
||||||
@ -59,20 +58,22 @@ instance Applicative (SealedForm url) where
|
|||||||
(g1, g2) <- g env
|
(g1, g2) <- g env
|
||||||
return (f1 <*> g1, f2 `mappend` g2)
|
return (f1 <*> g1, f2 `mappend` g2)
|
||||||
|
|
||||||
sealForm :: Form url a -> SealedForm url a
|
sealForm :: ([String] -> Hamlet url -> Hamlet url)
|
||||||
sealForm (Form form) = SealedForm $ \env -> liftM go (form env)
|
-> Form url a -> SealedForm url a
|
||||||
|
sealForm wrapper (Form form) = SealedForm $ \env -> liftM go (form env)
|
||||||
where
|
where
|
||||||
go (FormSuccess a, xml) = (Just a, xml [])
|
go (FormSuccess a, xml) = (Just a, wrapper [] xml)
|
||||||
go (FormFailure errs, xml) = (Nothing, xml errs)
|
go (FormFailure errs, xml) = (Nothing, wrapper errs xml)
|
||||||
go (FormMissing, xml) = (Nothing, xml [])
|
go (FormMissing, xml) = (Nothing, wrapper [] xml)
|
||||||
|
|
||||||
sealFormlet :: Formlet url a -> SealedFormlet url a
|
sealFormlet :: ([String] -> Hamlet url -> Hamlet url)
|
||||||
sealFormlet formlet initVal = sealForm $ formlet initVal
|
-> Formlet url a -> SealedFormlet url a
|
||||||
|
sealFormlet wrapper formlet initVal = sealForm wrapper $ formlet initVal
|
||||||
|
|
||||||
instance Functor (Form url) where
|
instance Functor (Form url) where
|
||||||
fmap f (Form g) = Form $ \env -> liftM (first $ fmap f) (g env)
|
fmap f (Form g) = Form $ \env -> liftM (first $ fmap f) (g env)
|
||||||
|
|
||||||
input' :: (String -> String -> [String] -> Hamlet url)
|
input' :: (String -> String -> Hamlet url)
|
||||||
-> Maybe String
|
-> Maybe String
|
||||||
-> Form url String
|
-> Form url String
|
||||||
input' mkXml val = Form $ \env -> do
|
input' mkXml val = Form $ \env -> do
|
||||||
@ -96,16 +97,13 @@ class Formable a where
|
|||||||
formable :: SealedFormlet url a
|
formable :: SealedFormlet url a
|
||||||
|
|
||||||
class Fieldable a where
|
class Fieldable a where
|
||||||
fieldable :: String -> Formlet url a
|
fieldable :: Formlet url a
|
||||||
|
|
||||||
instance Fieldable [Char] where
|
wrapperRow :: String -> [String] -> Hamlet url -> Hamlet url
|
||||||
fieldable label = input' go
|
wrapperRow label errs control = [$hamlet|
|
||||||
where
|
|
||||||
go name val errs = [$hamlet|
|
|
||||||
%tr
|
%tr
|
||||||
%th $string.label$
|
%th $string.label$
|
||||||
%td
|
%td ^control^
|
||||||
%input!type=text!name=$string.name$!value=$string.val$
|
|
||||||
$if not.null.errs
|
$if not.null.errs
|
||||||
%td.errors
|
%td.errors
|
||||||
%ul
|
%ul
|
||||||
@ -113,59 +111,36 @@ instance Fieldable [Char] where
|
|||||||
%li $string.err$
|
%li $string.err$
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
instance Fieldable [Char] where
|
||||||
|
fieldable = input' go
|
||||||
|
where
|
||||||
|
go name val = [$hamlet|
|
||||||
|
%input!type=text!name=$string.name$!value=$string.val$
|
||||||
|
|]
|
||||||
|
|
||||||
instance Fieldable Html where
|
instance Fieldable Html where
|
||||||
fieldable label =
|
fieldable = fmap preEscapedString . input' go . fmap (cs . renderHtml)
|
||||||
fmap preEscapedString
|
|
||||||
. input' go
|
|
||||||
. fmap (cs . renderHtml)
|
|
||||||
where
|
where
|
||||||
go name val errs = [$hamlet|
|
go name val = [$hamlet|%textarea!name=$string.name$ $string.val$|]
|
||||||
%tr
|
|
||||||
%th $string.label$
|
|
||||||
%td
|
|
||||||
%textarea!name=$string.name$
|
|
||||||
$string.val$
|
|
||||||
$if not.null.errs
|
|
||||||
%td.errors
|
|
||||||
%ul
|
|
||||||
$forall errs err
|
|
||||||
%li $string.err$
|
|
||||||
|]
|
|
||||||
|
|
||||||
instance Fieldable Day where
|
instance Fieldable Day where
|
||||||
fieldable label x = input' go (fmap show x) `check` asDay
|
fieldable x = input' go (fmap show x) `check` asDay
|
||||||
where
|
where
|
||||||
go name val errs = [$hamlet|
|
go name val = [$hamlet|
|
||||||
%tr
|
%input!type=date!name=$string.name$!value=$string.val$
|
||||||
%th $string.label$
|
|
||||||
%td
|
|
||||||
%input!type=date!name=$string.name$!value=$string.val$
|
|
||||||
$if not.null.errs
|
|
||||||
%td.errors
|
|
||||||
%ul
|
|
||||||
$forall errs err
|
|
||||||
%li $string.err$
|
|
||||||
|]
|
|]
|
||||||
asDay s = case reads s of
|
asDay s = case reads s of
|
||||||
(x, _):_ -> Right x
|
(y, _):_ -> Right y
|
||||||
[] -> Left ["Invalid day"]
|
[] -> Left ["Invalid day"]
|
||||||
|
|
||||||
newtype Slug = Slug { unSlug :: String }
|
newtype Slug = Slug { unSlug :: String }
|
||||||
deriving (Read, Eq, Show, SinglePiece, Persistable)
|
deriving (Read, Eq, Show, SinglePiece, Persistable)
|
||||||
|
|
||||||
instance Fieldable Slug where
|
instance Fieldable Slug where
|
||||||
fieldable label x = input' go (fmap unSlug x) `check` asSlug
|
fieldable x = input' go (fmap unSlug x) `check` asSlug
|
||||||
where
|
where
|
||||||
go name val errs = [$hamlet|
|
go name val = [$hamlet|
|
||||||
%tr
|
%input!type=text!name=$string.name$!value=$string.val$
|
||||||
%th $string.label$
|
|
||||||
%td
|
|
||||||
%input!type=text!name=$string.name$!value=$string.val$
|
|
||||||
$if not.null.errs
|
|
||||||
%td.errors
|
|
||||||
%ul
|
|
||||||
$forall errs err
|
|
||||||
%li $string.err$
|
|
||||||
|]
|
|]
|
||||||
asSlug [] = Left ["Slug must be non-empty"]
|
asSlug [] = Left ["Slug must be non-empty"]
|
||||||
asSlug x'
|
asSlug x'
|
||||||
@ -173,6 +148,17 @@ instance Fieldable Slug where
|
|||||||
Right $ Slug x'
|
Right $ Slug x'
|
||||||
| otherwise = Left ["Slug must be alphanumeric, - and _"]
|
| otherwise = Left ["Slug must be alphanumeric, - and _"]
|
||||||
|
|
||||||
|
newtype NonEmptyString = NonEmptyString { unNonEmptyString :: String }
|
||||||
|
deriving (Read, Eq, Show, SinglePiece, Persistable)
|
||||||
|
instance Fieldable NonEmptyString where
|
||||||
|
fieldable x = input' go (fmap unNonEmptyString x) `check` notEmpty
|
||||||
|
where
|
||||||
|
go name val = [$hamlet|
|
||||||
|
%input!type=text!name=$string.name$!value=$string.val$
|
||||||
|
|]
|
||||||
|
notEmpty "" = Left ["Must be non-empty"]
|
||||||
|
notEmpty x = Right $ NonEmptyString x
|
||||||
|
|
||||||
share2 :: Monad m => (a -> m [b]) -> (a -> m [b]) -> a -> m [b]
|
share2 :: Monad m => (a -> m [b]) -> (a -> m [b]) -> a -> m [b]
|
||||||
share2 f g a = do
|
share2 f g a = do
|
||||||
f' <- f a
|
f' <- f a
|
||||||
@ -201,7 +187,8 @@ deriveFormable = mapM derive
|
|||||||
return $ InstanceD [] (ConT ''Formable `AppT` ConT (mkName $ tableName t))
|
return $ InstanceD [] (ConT ''Formable `AppT` ConT (mkName $ tableName t))
|
||||||
[FunD (mkName "formable") [c1, c2]]
|
[FunD (mkName "formable") [c1, c2]]
|
||||||
go ap just' = foldl (ap' ap) just' . map go'
|
go ap just' = foldl (ap' ap) just' . map go'
|
||||||
go' (label, ex) = VarE (mkName "sealForm") `AppE`
|
go' (label, ex) =
|
||||||
(VarE (mkName "fieldable")
|
VarE (mkName "sealForm") `AppE`
|
||||||
`AppE` LitE (StringL label) `AppE` ex)
|
(VarE (mkName "wrapperRow") `AppE` LitE (StringL label)) `AppE`
|
||||||
|
(VarE (mkName "fieldable") `AppE` ex)
|
||||||
ap' ap x y = InfixE (Just x) ap (Just y)
|
ap' ap x y = InfixE (Just x) ap (Just y)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user