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

Support field-level validation with variants #14

Merged
merged 44 commits into from Aug 12, 2018

Conversation

1 participant
@thomashoneyman
Copy link
Owner

thomashoneyman commented Aug 7, 2018

What does this pull request do?

This PR introduces a fix for #11. Validation was previously done by providing a form InputField -> m (form InputField) function, which would run any time the Validate query was triggered. In effect, each field's validation was bundled up into one validation function that ran on all fields any time validation was triggered on any individual field. Perhaps not the worst issue in the world -- unless validation on a field was expensive or had side-effects. Imagine a single key press in an unrelated text field triggering several server calls!

This PR changes the Modify and Validate queries to instead take a variant. The variant notes which field is meant to be updated or validated and only runs the relevant function on that field. There is still a ValidateAll function that makes it possible to run all validators.

Finally, it ensures that you can still perform these types of validation:

  1. You can supply per-field validation (i -> m (Either e o))
  2. Your field-level validation has access to the other fields in the form so that you can do dependent validations (password fields must be equal, for example)
  3. Your field-level validation has access to some additional state from other, unrelated forms so you can use that for dependent validation (for example, several forms linked together)

How should this be manually tested?

Verify that the examples still behave as expected.

Other Notes:

This PR is a work in progress. There is still a bit more to do:

  • Project documentation, like the overview, will need to be updated
  • There are still a few places where it's awkward and cumbersome to create forms that I'd like to clean up (for example: pure <<< F.unwrapRecord <<< unwrap).

The validation problem, however, is solved.

thomashoneyman added some commits Jul 31, 2018

WIP
WIP
..?
@thomashoneyman

This comment has been minimized.

Copy link
Owner

thomashoneyman commented on src/Formless.purs in adee883 Aug 4, 2018

This should be an unreachable case, existing only so that validators have access to the full form state when they run. The user is still obligated to provide validators -- they're, at the moment, not optional. Though perhaps they could omit validators so long as the input and output types are the same.

@thomashoneyman

This comment has been minimized.

Copy link
Owner

thomashoneyman commented on src/Spec/Spec.purs in adee883 Aug 4, 2018

At this point I've essentially converged on the Validation type from Polyform:

newtype Validation m e a b = a -> m (V e b)

except I'm relying on Either under the hood. I don't have a particularly good reason for this besides not wanting to be tied to a particular validation library.

@thomashoneyman thomashoneyman added this to the 0.2.0 milestone Aug 7, 2018

@thomashoneyman thomashoneyman self-assigned this Aug 7, 2018

@thomashoneyman

This comment has been minimized.

Copy link
Owner

thomashoneyman commented Aug 10, 2018

Currently still a bug: the validators have access to global state at form initialization, but then continue to reference that first original value forever afterward. Need to be updated to pull new state on each run.

@thomashoneyman

This comment has been minimized.

Copy link
Owner

thomashoneyman commented Aug 11, 2018

2018-08-10 20 53 51

Still not quite there -- fields do update with the latest state on every change, but fields that are not being validated but depend on other fields can fall out of sync.

thomashoneyman added some commits Aug 11, 2018

[ HP.value $ F.getInput prx.secretKey1 st.form
, HE.onValueInput $ HE.input \str -> F.AndThen
(F.modifyValidate_ prx.secretKey1 str)
(F.validate_ prx.secretKey2)

This comment has been minimized.

@thomashoneyman

thomashoneyman Aug 11, 2018

Owner

This is an example of how you can make sure dependent fields are also validated.

thomashoneyman added some commits Aug 11, 2018

@thomashoneyman thomashoneyman merged commit 4776cc5 into master Aug 12, 2018

1 check passed

ci/circleci: test Your tests passed on CircleCI!
Details

@thomashoneyman thomashoneyman deleted the variant branch Aug 12, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment