Skip to content

Commit 56cebf4

Browse files
author
Madeline Trotter
authored
Add a wrapper for traversing newtypes in formdata (#183)
1 parent faba9ed commit 56cebf4

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

docs/Examples/Form.example.purs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Data.Array.NonEmpty (NonEmptyArray)
1010
import Data.Foldable (foldMap)
1111
import Data.Int as Int
1212
import Data.Lens (iso)
13+
import Data.Lens.Iso (mapping)
1314
import Data.Lens.Record (prop)
1415
import Data.Maybe (Maybe(..), isNothing, maybe)
1516
import Data.Monoid as Monoid
@@ -30,6 +31,7 @@ import Lumi.Components.Form (FormBuilder, Validated)
3031
import Lumi.Components.Form as F
3132
import Lumi.Components.Form.Defaults (formDefaults)
3233
import Lumi.Components.Form.Table as FT
34+
import Lumi.Components.Form.Validation (ValidatedNewtype, _ValidatedNewtype)
3335
import Lumi.Components.Input as Input
3436
import Lumi.Components.LabeledField (RequiredField(..))
3537
import Lumi.Components.Modal (dialog)
@@ -199,7 +201,9 @@ type User =
199201
, descriptiveCheckbox :: Boolean
200202
, height :: Validated String
201203
, addresses :: Validated (Array Address)
202-
, pets :: Validated (Array Pet)
204+
, pets :: Validated (Array (ValidatedNewtype Pet))
205+
-- ^ validation helpers like `setModified` need a little assistance getting
206+
-- into Newtypes like `Pet`, hence this `ValidatedNewtype` wrapper
203207
, leastFavoriteColors :: Validated (Array String)
204208
, notes :: String
205209
, avatar :: Maybe Upload.FileId
@@ -220,14 +224,16 @@ type ValidatedUser =
220224
, avatar :: Maybe Upload.FileId
221225
}
222226

223-
type Pet =
227+
newtype Pet = Pet
224228
{ firstName :: Validated String
225229
, lastName :: Validated String
226230
, animal :: Validated (Maybe String)
227231
, age :: Validated String
228232
, color :: Validated (Maybe String)
229233
}
230234

235+
derive instance ntPet :: Newtype Pet _
236+
231237
type ValidatedPet =
232238
{ name :: NonEmptyString
233239
, animal :: String
@@ -337,7 +343,7 @@ userForm = ado
337343

338344
F.section "Pets"
339345
pets <-
340-
F.focus (prop (SProxy :: SProxy "pets"))
346+
F.focus (prop (SProxy :: SProxy "pets") <<< mapping (mapping _ValidatedNewtype))
341347
$ F.warn (\pets ->
342348
Monoid.guard (Array.null pets) (pure "You should adopt a pet.")
343349
)

src/Lumi/Components/Form/Validation.purs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Lumi.Components.Form.Validation
1010
, _Validated, _Fresh, _Modified
1111
, setFresh, setModified
1212
, ModifyValidated(..)
13+
, ValidatedNewtype(..), _ValidatedNewtype
1314
, class CanValidate, fresh, modified, fromValidated
1415
, validated
1516
, warn
@@ -26,10 +27,11 @@ import Data.Enum (toEnum)
2627
import Data.Eq (class Eq1)
2728
import Data.Foldable (foldMap)
2829
import Data.Int as Int
29-
import Data.Lens (Lens, Prism', lens, over, prism', review, view)
30+
import Data.Lens (Lens, Prism', Iso', lens, over, prism', review, view)
31+
import Data.Lens.Iso.Newtype (_Newtype)
3032
import Data.Maybe (Maybe(..))
3133
import Data.Monoid (guard)
32-
import Data.Newtype (un)
34+
import Data.Newtype (class Newtype, un)
3335
import Data.Nullable (notNull)
3436
import Data.Number as Number
3537
import Data.Ord (class Ord1)
@@ -201,6 +203,13 @@ setModified = mapping (ModifyValidated (Modified <<< view _Validated))
201203
-- | records containing `Validated` values.
202204
newtype ModifyValidated = ModifyValidated (Validated ~> Validated)
203205

206+
newtype ValidatedNewtype a = ValidatedNewtype a
207+
208+
derive instance ntMVP :: Newtype (ValidatedNewtype a) _
209+
210+
_ValidatedNewtype :: forall s a. Newtype s a => Iso' (ValidatedNewtype s) a
211+
_ValidatedNewtype = _Newtype <<< _Newtype
212+
204213
instance modifyValidated :: Mapping ModifyValidated a a => Mapping ModifyValidated (Validated a) (Validated a) where
205214
mapping m@(ModifyValidated f) = over _Validated (mapping m) <<< f
206215
else instance modifyValidatedRecord ::
@@ -210,6 +219,8 @@ else instance modifyValidatedRecord ::
210219
mapping d = hmap d
211220
else instance modifyValidatedArray :: Mapping ModifyValidated a a => Mapping ModifyValidated (Array a) (Array a) where
212221
mapping d = map (mapping d)
222+
else instance modifyValidatedNewtype :: (Newtype a b, Mapping ModifyValidated b b) => Mapping ModifyValidated (ValidatedNewtype a) (ValidatedNewtype a) where
223+
mapping d = over (_Newtype <<< _Newtype) (mapping d)
213224
else instance modifyValidatedIdentity :: Mapping ModifyValidated a a where
214225
mapping _ = identity
215226

0 commit comments

Comments
 (0)