Validation spanning multiple fields

2019-06-18 05:04发布

问题:

I'm trying to grok applicative forms, and I've been wondering how to implement a form that validates fields that depend on other fields. For example a registration form which has password and confirm_password fields and I'd like to validate that password == confirm_password.

I could be done after the form has ran, in the handler, but that would mean losing error messages.

Edit: Forgot to mention, I'm mainly using Yesods applicative forms, but they seem to be quite close to digestive-functors

回答1:

What type of form system are you using? You can easily do this with digestive-functors, here's an example of one of my registration forms:

registrationForm =
    Registration
      <$> "username" .: text Nothing
      <*> "password" .: passwordConfirmer
  where passwordConfirmer =
          validate fst' $ (,) <$> ("p1" .: text Nothing)
                              <*> ("p2" .: text Nothing)
        fst' (p1, p2) | p1 == p2  = Success p1
                      | otherwise = Error "Passwords must match"

Here you can see I generate a value for my 'password' field by using my passwordConfirmer form field. This field uses 2 text fields and puts them into a tuple, but after validation it just takes the fst element (though it could take snd, we've guaranteed they are equal!).

My Registration type is:

data Registration = Registration
    { regUserName :: Text
    , regPassword :: Text
    }