-
-
Notifications
You must be signed in to change notification settings - Fork 32
-
-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Force validation on non dirty fields? #32
Comments
The current design of the library only validates fields that are in a I don't have a firm opinion one way or another, but as this seemed like a source of unnecessary boilerplate I opted to just have validators run on touched fields. Short-term solutionOK -- enough background! Until anything about that design has been changed, this is one approach you could take. Here's a code snippet from the "real world" example for when you'd like to validate that one secret key field is equal to the other one: renderSecretKey1 :: FormlessState -> FormlessHTML
renderSecretKey1 st =
UI.input
{ label: "Secret Key 1"
, help: UI.resultToHelp
"Provide a secret identifier for the group"
(F.getResult prx.secretKey1 st.form)
, placeholder: "ia30<>Psncdi3b#$<0423"
}
[ HP.value $ F.getInput prx.secretKey1 st.form
, HE.onValueInput $ HE.input \str -> F.AndThen
(F.modifyValidate_ prx.secretKey1 str)
(F.validate_ prx.secretKey2)
] The tricky part about this situation is that This is possible with the F.AndThen
(F.DoThis value)
(F.AndThen
(F.DoThat value)
(F.DoThen value)
) You could move this code... let e = F.getInput prx.email f.form
void $ H.query' CP.cp1 unit $ F.modifyValidate_ prx.email e ... to instead be part of your rendering for the checkbox, so that when the checkbox is toggled, the email field is modified to its same value and validated. It's not THAT much better, but at least it's not cluttering up your Longer-term solutionsThere are some other ways that things could be better:
Let me know if this helps! |
Well, I have to disagree: this solution is way better as it helps keeping all form related things to the form component without leaking to the parent. Regarding the long-term solutions:
Thanks again! :) EDIT: |
Oh no! Did you find an alternate solution? Sorry that didn't work for you; I'd love to hear why. |
Well, yes the problem was still that I had to validation on the untouched field, but in the end I decided it wasn't that important! checkoutEmail
:: forall form m e o e1 o1 t.
Newtype (form Record FormField) { sendVoucher :: FormField e Boolean o, sendEmail :: FormField e1 Boolean o1 | t } =>
Monad m =>
Validation form m FieldError String (Maybe String)
checkoutEmail = Validation $ \form email ->
let sV = F.getInput (SProxy :: SProxy "sendVoucher") form
sE = F.getInput (SProxy :: SProxy "sendEmail") form
in if sV || sE
then runValidation (nonEmptyStr >>> validEmail >>> F.hoistFn_ Just) form email
else runValidation (acceptEmpty validEmail) form email And I ended up with this abstraction that will let me use chained validators in the future: defaults ::
forall rall rsub rx.
Row.Union rsub rall rx =>
Row.Nub rx rall =>
{ | rsub } ->
{ | rall } ->
{ | rall }
defaults = Record.merge
type FieldConfigRow' r =
( label :: String
, id_ :: Maybe String
, help :: String
, required :: Boolean
, disabled :: Boolean
, placeholder :: String
, expanded :: Boolean
| r
)
type FieldConfigRow s pq cq cs form out m a i =
FieldConfigRow'
( sym :: SProxy s
, onInput :: Maybe (i -> Unit -> F.Query pq cq cs form out m Unit)
)
type FieldConfig' = Record (FieldConfigRow' ())
type FieldConfig sym pq cq cs form out m a i = Record (FieldConfigRow sym pq cq cs form out m a i)
fieldConf' :: FieldConfig'
fieldConf' = { label: ""
, id_: Nothing
, help: ""
, required: false
, disabled: false
, placeholder: ""
, expanded: false
}
fieldConf :: forall sym. FieldConfig sym
fieldConf = Record.merge { sym: SProxy :: SProxy sym } fieldConf'
fieldConf :: forall sym pq cq cs form out m a i. FieldConfig_ sym pq cq cs form out m a i
fieldConf = Record.merge { onInput: Nothing, sym: SProxy :: SProxy sym } fieldConf'
buildConf' ::
forall rsub rx.
Row.Nub rx (FieldConfigRow' ()) =>
Row.Union rsub (FieldConfigRow' ()) rx =>
{ | rsub } ->
FieldConfig'
buildConf' r = defaults r fieldConf'
buildConf ::
forall sym rsub rx pq cq cs form out m a e i o t1 inputs.
IsSymbol sym =>
Newtype (form Variant F.InputField) (Variant inputs) =>
Row.Cons sym (F.InputField e i o) t1 inputs =>
Row.Nub rx (FieldConfigRow_ sym pq cq cs form out m a i) =>
Row.Union rsub (FieldConfigRow_ sym pq cq cs form out m a i) rx =>
{ | rsub } ->
FieldConfig_ sym pq cq cs form out m a i
buildConf r = defaults r fieldConf
inputHandler ::
forall sym pq cq cs form out m a e i o inputs t1.
IsSymbol sym =>
Newtype (form Variant F.InputField) (Variant inputs) =>
Row.Cons sym (F.InputField e i o) t1 inputs =>
FieldConfig sym pq cq cs form out m a i ->
(i -> Unit -> F.Query pq cq cs form out m Unit)
inputHandler { sym, onInput } = case onInput of
Nothing -> F.modifyValidate sym
Just oi -> oi
-- An example checkbox
checkbox ::
forall sym pq cq cs form out m a e t0 t1 inputs rsub rx fields.
IsSymbol sym =>
Newtype (form Record F.FormField) { | fields } =>
Newtype (form Variant F.InputField) (Variant inputs) =>
Row.Cons sym (F.FormField e Boolean Boolean) t0 fields =>
Row.Cons sym (F.InputField e Boolean Boolean) t1 inputs =>
Row.Nub rx (FieldConfigRow sym pq cq cs form out m a Boolean) =>
Row.Union rsub (FieldConfigRow sym pq cq cs form out m a Boolean) rx =>
{ | rsub} ->
F.State form out m ->
H.ParentHTML (F.Query pq cq cs form out m) cq cs m
checkbox conf { form } =
let c :: FieldConfig sym pq cq cs form out m a Boolean
c = buildConf conf
in
UI.singleField
[ HH.label
[ HP.class_ B.checkbox ]
[ HH.input
[ HP.type_ HP.InputCheckbox
, HP.checked $ F.getInput c.sym form
, HE.onChecked $ HE.input (inputHandler c)
, HP.disabled c.disabled
]
, HH.text c.label
]
] This lets me build working formless fields with as little as: Form.checkbox { label: "Hello", sym: (SProxy :: SProxy "helloField") } state |
@dariooddenino This issue is closed in #34, using the first solution proposed above. |
Hi, not sure if I missed something in the code (and sorry for the spam), but here's what I need to do:
I have an email field and a "send email" checkbox. The email field becomes mandatory when the the checkbox is checked.
The problem is that I want the "missing email" error to appear as soon as the user checks the "send email" field and I had to resort to this solution which feels a little hacky:
I can't use
validate_
, as nothing will happen if the email field was still untouched.The text was updated successfully, but these errors were encountered: