Hi!
I’d like to know what’s the best way to check for dirty forms state and to reinitialize forms with the “new” formless api (it took me a while to catch up…).
After a bit of tinkering (and some help from discord) I got to this solution, but I wanted to know if there’s a more appropriate way to get to the same result.
I have defined two helper functions:
data DirtyProps = DirtyProps
instance
( Eq a
, TE.TypeEquals (Record (value :: a, initialValue :: a | tail)) (Record row)
) =>
FoldingWithIndex DirtyProps (Proxy sym) Boolean (Record row) Boolean where
foldingWithIndex DirtyProps _prop b a = b || val1 /= val2
where
val1 = TE.to <<< Record.get (Proxy :: Proxy "value") <<< TE.from $ a
val2 = TE.to <<< Record.get (Proxy :: Proxy "initialValue") <<< TE.from $ a
data ReinitForm = ReinitForm
instance
( TE.TypeEquals (Record (value :: a, initialValue :: a, result :: Maybe (Either e o))) (Record row)
) =>
Mapping ReinitForm a (Record row) where
mapping ReinitForm val =
TE.to { value: val, initialValue: val, result: Nothing }
where
_initialValue = Proxy :: Proxy "initialValue"
_value = Proxy :: Proxy "value"
_result = Proxy :: Proxy "result"
-- | Checks whether a Formless form is dirty.
isFormDirty :: forall r. HFoldlWithIndex DirtyProps Boolean { | r } Boolean => { | r } -> Boolean
isFormDirty r = hfoldlWithIndex DirtyProps false r
-- | Reinitializes a Formless form with new inputs values.
reinitForm = hmap ReinitForm
In this case I have a wrapper component that contains a form. A lot of code omitted and simplified to highlight the important parts:
component =
Hooks.component \{slotToken } input -> Hooks.do
Hooks.pure do
HH.slot _form unit (form input) mempty (handleForm slotToken)
where
handleForm slotToken = case _ of
Submit formRes -> do
newInput <- someLogicAndAjaxCall
Hooks.tell slotToken _form unit (Update newInput)
form input = F.formless { ... } input $ H.mkComponent
...
where
handleQuery = case _ of
F.Query (Update newInput a) -> do
{ context: { formActions } } <- H.get
handleAction $ formActions.setFields $ reinitForm newInput
pure $ Just a
F.Validate changed reply -> do
{ context: { fields } } <- H.get
when isFormDirty fields $ do
-- do some stuff like onbeforeunload
pure $ Just $ reply $ F.validate changed etc.