Skip to content
This repository has been archived by the owner on May 2, 2024. It is now read-only.

How to validate form fields which should have same values #75

Closed
alexofob opened this issue Dec 30, 2016 · 5 comments
Closed

How to validate form fields which should have same values #75

alexofob opened this issue Dec 30, 2016 · 5 comments

Comments

@alexofob
Copy link

Hi @etaque ,

This issue is related to issue 66 which was previously closed.

I have implemented your recommendation on how to do the password confirmation as below:

`validateChangePwdForm : Validation CustomError ChangePwdForm
validateChangePwdForm =
map2 ChangePwdForm
(field "newPassword" validatePassword)
(field "confirmPassword" string |> andThen passwordsMatch)

passwordsMatch : String -> Validation CustomError String
passwordsMatch confirmPassword =
(field "newPassword" string)
|> andThen
(\s ->
if (s /= confirmPassword) then
fail (customError PasswordsMustMatch)
else
succeed s
)`

And I am using the below code to show the error message when the passwords do not much.

`
let
password =
Form.getFieldAsString "confirmPassword" changePwdForm

( passwordError, invalid ) =
    case password.liveError of
        Just errorValue ->
            case errorValue of
                Form.Error.Empty ->
                    ( "Please confirm your password.", attribute "invalid" "" )

                Form.Error.CustomError PasswordsMustMatch ->
                    ( "Passwords must match", attribute "invalid" "" )

                _ ->
                    ( "Please provide a valid Password.", attribute "invalid" "" )

        Nothing ->
            ( "", class "" )

`
However, I am unable to see the Error message when the input is validated.

What am I doing wrong?

From the troubleshooting I have done so far, it seems that the line

fail (customError PasswordsMustMatch)

is failing to return the validation.

I will appreciate your feedback.

Thanks.

@alexofob
Copy link
Author

alexofob commented Dec 31, 2016

I have done some further troubleshooting and it seems that reading 2 different fields as I had shown above does not make it possible to track the error in the field's error state. One field is nested into another and the error states are not updated at all when validating the fields.
We may have to look into another way of solving this issue.

I will appreciate your comments.

@etaque
Copy link
Owner

etaque commented Dec 31, 2016

Hi, I think you're quite close, it's just a question of precedence and parenthesis now. I got it working with this adaptation of lib's example:

validate : Validation CustomError User
validate =
    map8
        User
        (field "name" (string |> andThen nonEmpty))
        (field "email" (email |> andThen (asyncCheck True)))
        (field "password" (string |> andThen (minLength 4)))
        ((field "password" string) |> andThen validateConfirmation)
        (field "admin" (bool |> defaultValue False))
        (field "date" date)
        (field "profile" validateProfile)
        (field "todos" (list validateTodo))


validateConfirmation : String -> Validation CustomError String
validateConfirmation password =
    field "passwordConfirmation"
        (string
            |> andThen
                (\confirmation ->
                    if password == confirmation then
                        succeed confirmation
                    else
                        fail (customError ConfirmationError)
                )
        )

That could be better, I'm trying to create a helper that would enable us to write field "passwordConfirmation" string |> andThen (confirm "password")

@alexofob
Copy link
Author

Great stuff @etaque.

This works!

Many thanks.

@felixLam
Copy link

This was genuinely helpful. I found this thanks to the help from david_hernandez on slack. Maybe this should be part of some example or in the Readme as this serves as a simple example of interdependent validation.

@kyasu1
Copy link

kyasu1 commented Apr 8, 2017

Hi,

Thank you for the great works, this library helped me so much since I need to write a lot of forms views...

While working with this validation example, I noticed it was not trivial to show user friendly error messages. Adding |> withCustomError at the end of password validation does not show the expected message but InvalidString or Empty depending on the initial edit or not. This annoying behavior may be caused by the validation error from (field "password" string) on the next line which has a higher priority than custom errors.

Anyway I figured out a workaround and so wanted to share it.

Simplified original example: Code on Ellie

validate : Validation String User
validate =
    succeed User
        |> andMap (field "name" (string |> withCustomError "Input Name !"))
        |> andMap (field "password" (string |> withCustomError "Input Password !"))
        |> andMap ((field "password" string) |> andThen validateConfirmation)


validateConfirmation : String -> Validation String String
validateConfirmation password =
    field "passwordConfirmation"
        (string
            |> andThen
                (\confirmation ->
                    if password == confirmation then
                        succeed confirmation
                    else
                        fail (customError "Confirmation Error")
                )
        )

Example with user friendly error messages: Code on Ellie

validate : Validation String User
validate =
    succeed User
        |> andMap (field "name" (string |> withCustomError "Input Name !"))
        |> andMap (field "password" (string |> withCustomError "Input Password !"))
        |> andMap 
            (oneOf 
                [ (field "password" string) |> andThen validateConfirmation
                , emptyString |> andThen validateConfirmation
                ]
              )


validateConfirmation : String -> Validation String String
validateConfirmation password =
    field "passwordConfirmation"
        (string
            |> withCustomError "Input Password Confimation !"
            |> andThen
                (\confirmation ->
                    if password == confirmation then
                        succeed confirmation
                    else
                        fail (customError "Confirmation Error")
                )
        )

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants