Skip to content

Add `@validateOn="input", rename "blur" to "focusout" #31

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

Merged
merged 3 commits into from
Feb 7, 2023

Conversation

simonihmig
Copy link
Contributor

When playing with validations in a real demo rather than just looking for tests to become green, I realised that the behaviour we likely want for revalidation is not given when using @revalidationOn="change". We want to have revalidation happen as soon as you type (into an invalid field) and it turns valid, without having to focus out of the input (which would effectively be @revalidationOn="blur"). But change does not trigger right while typing for inputs (normal texts inputs, checkboxes, radios and select boxes this is different though), only when focussing out ("committing"). (see change event).

So this introduces another option @revalidationOn="input", listening for the input event:

image

The PR also takes this as a opportunity to rename @(re)validationOn="blur" to @(re)validationOn="focusout", as this is the event we are actually listening to, and having one value for the public API and another for the internal implementation did not really serve a meaningful purpose (other than maybe blur being a bit more common), but could likely cause confusion.

@changeset-bot
Copy link

changeset-bot bot commented Feb 6, 2023

⚠️ No Changeset found

Latest commit: b099152

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@nicolechung
Copy link
Contributor

Release questions:

  1. Are we doing releases yet? Because I guess this would be a breaking change (since we are changing "blur" to "focusout" but since we haven't released anything yet I guess this is not.
  2. If we are doing releases, do we look for the changeset in this PR? (I feel like I have asked this question before in another repo...clearly I don't have a lot of hands on practise with changesets yet)

@NullVoxPopuli
Copy link
Contributor

NullVoxPopuli commented Feb 6, 2023

Are we doing releases yet?

not yet -- I've opened this: #30
and it starts us out with beta releases, so breaking changes are non-major.

#30 has all the context for how to start releases if we want to publish to npm

do we look for the changeset in this PR?

as we are all maintainers, yes (again, if we're releasing).
if this PR were from an outside contributor, one of us maintainers would add the changeset before merging.

However, #30 is a blocker for doing any changeset / release stuff

* This mimics the behavior of a user typing data into an input without yet focusing out of it. Browsers will only trigger a `change` event when focusing
* out of the element, not while typing!
*
* `fillIn` will basically simulate entering the data *and* kinda focusing out (as it triggers `change`, however not `focusout`, which is impossible to achieve as a real user),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😮 I did NOT know this!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, had to confirm this for myself by looking up their source.

I should probably create an issue. I guess we cannot change the existing behaviour of fillIn, as that would break every app. But maybe we can upstream some additional helpers that cover the different real-world use cases better...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { find, triggerEvent } from '@ember/test-helpers';

/**
* Fill the provided text into the `value` property of the selected form element, similar to `fillIn`, but *without* implicitly triggering a `change` event.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10/10 would read again

assert
.dom('[data-test-first-name-errors]')
.doesNotExist(
'validation errors are not rendered before validation happens on change'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: on change -> on input. Since this test is now testing for input not change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh ya, thanks! A lot of boilerplate in those tests, that I just copy-pased from the change tests. Fixed that!

.dom('[data-test-first-name-errors]')
.exists(
{ count: 1 },
'validation errors appear on focusout when validation fails'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: on focusout -> on input.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we want to test that there are no errors on the last name field (by accident)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do, just a few lines below!

'validation errors are not rendered before initial validation happens before form is filled in'
);

await fillIn('[data-test-first-name]', 'Foo');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want input here or fillIn?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @simonihmig is doing something similar here as the above tests - ensuring fillIn doesn't cause errors to render, but below on line 1976 where he's using input it does

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it doesn't matter in this case too because the revalidate doesn't start until after submit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it doesn't matter here. And fillIn is basically doing more as explained elsewhere (triggering input and change events), so when even fillIn does not make errors show up, then input would neither.

Copy link
Contributor

@nicolechung nicolechung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this!

Copy link
Contributor

@ynotdraw ynotdraw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look great to me! Looks like a lingering @validateOn="blur" which is causing CI to be red

 error TS2322: Type '"blur"' is not assignable to type 'ValidateOn | undefined'.

* This mimics the behavior of a user typing data into an input without yet focusing out of it. Browsers will only trigger a `change` event when focusing
* out of the element, not while typing!
*
* `fillIn` will basically simulate entering the data *and* kinda focusing out (as it triggers `change`, however not `focusout`, which is impossible to achieve as a real user),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL

'validation errors are not rendered before initial validation happens before form is filled in'
);

await fillIn('[data-test-first-name]', 'Foo');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @simonihmig is doing something similar here as the above tests - ensuring fillIn doesn't cause errors to render, but below on line 1976 where he's using input it does

@simonihmig
Copy link
Contributor Author

Changes look great to me! Looks like a lingering @validateOn="blur" which is causing CI to be red

Right, thank you! Fixed that. Good to see that Glint is actually working 🙂

@simonihmig simonihmig merged commit 0f49c29 into main Feb 7, 2023
@simonihmig simonihmig deleted the revalidate-input branch February 7, 2023 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants