This repository has been archived by the owner on Mar 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
v1.2.0 – Add support for both blur and keyup events. (#31)
We've added f-validate to a new project, however there's a few things we need to add before we get feature parity with solution we're replacing. The previous solution uses [jQuery Validate](https://github.com/jquery-validation/jquery-validation/). The default behaviour of this library is to delay validation until the input blur event has fired once. This provides an UX improvement of not seeing a validation error before the user has finished typing. This is most useful when the validation type is email or min-length. This PR attempts to recreate that logic. A few things: - I couldn't think of a better name than `hybridMode` which I appreciate isn't great 😄 - I've tried to make minimal changes to the existing code - There's not really any tests around any of this yet. If this approach looks OK, I'll add additional tests to cover these scenarios ## UI Review Checks - [x] UI Documentation has been [updated] - [x] JavaScript Tests have been [updated] - [x] Module has been tested in Global Documentation ## Browsers Tested - [x] Chrome - [x] Edge - [ ] Internet Explorer 11 - [x] Mobile (i.e. iPhone/Android - please list device) ### List any other browsers that this PR has been tested in: - [View our supported browser list](https://fozzie.just-eat.com/documentation/general/browser-support)
- Loading branch information
1 parent
e30114e
commit 19ad2b8
Showing
7 changed files
with
248 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
module.exports = { | ||
moduleFileExtensions: [ | ||
'js', | ||
'json', | ||
'vue' | ||
], | ||
|
||
moduleNameMapper: { | ||
'\\.(jpg|jpeg|png|gif||svg|)$': '<rootDir>/fileMock.js', | ||
'\\.(css|scss)$': '<rootDir>/styleMock.js' | ||
}, | ||
|
||
transform: { | ||
'^.+\\.js$': 'babel-jest' | ||
}, | ||
|
||
collectCoverageFrom: [ | ||
'assets/js/**/*.js', | ||
'!assets/js/shims/**', | ||
'!**/locales/**', | ||
'!**/node_modules/**' | ||
], | ||
|
||
testURL: 'http://localhost/', | ||
|
||
snapshotSerializers: [ | ||
] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`hybridMode should not validate on keydown before initial blur 1`] = ` | ||
"<form novalidate=\\"\\"> | ||
<input type=\\"email\\" name=\\"email\\"> | ||
</form>" | ||
`; | ||
exports[`hybridMode should validate on form submit 1`] = ` | ||
"<form novalidate=\\"\\" class=\\"has-error\\"> | ||
<input type=\\"text\\" required=\\"\\" class=\\"has-error\\"><p class=\\"form-error\\">This field is required.</p> | ||
<input type=\\"email\\" name=\\"email\\" class=\\"has-error\\" data-blurred=\\"\\"><p class=\\"form-error\\">This field must contain a valid email address.</p> | ||
</form>" | ||
`; | ||
exports[`hybridMode should validate on keydown after initial blur 1`] = ` | ||
"<form novalidate=\\"\\" class=\\"has-error\\"> | ||
<input type=\\"email\\" name=\\"email\\" class=\\"has-error\\" data-blurred=\\"\\"><p class=\\"form-error\\">This field must contain a valid email address.</p> | ||
</form>" | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import TestUtils from 'js-test-buddy'; | ||
import FormValidation from '../src'; | ||
|
||
describe('hybridMode', () => { | ||
|
||
it('should throw error if hyrbid mode is used with a validateOn event', () => { | ||
|
||
// Arrange | ||
TestUtils.setBodyHtml(`<form> | ||
<input required value="x" /> | ||
<input required> | ||
</form>`); | ||
const form = document.querySelector('form'); | ||
|
||
// Act & Assert | ||
expect(() => { | ||
// eslint-disable-next-line no-new | ||
new FormValidation(form, { | ||
hybridMode: true, | ||
validateOn: 'blur' | ||
}); | ||
}).toThrowError('f-validate: hybridMode cannot be used with the validateOn option'); | ||
|
||
}); | ||
|
||
it('should throw error if hyrbid mode is used with grouped errors', () => { | ||
|
||
// Arrange | ||
TestUtils.setBodyHtml(`<form> | ||
<input required value="x" /> | ||
<input required> | ||
</form>`); | ||
const form = document.querySelector('form'); | ||
|
||
// Act & Assert | ||
expect(() => { | ||
// eslint-disable-next-line no-new | ||
new FormValidation(form, { | ||
hybridMode: true, | ||
groupErrorPlacement: true | ||
}); | ||
}).toThrowError('f-validate: hybridMode cannot be used if errors are grouped'); | ||
|
||
}); | ||
|
||
it('should bind events if configuration is valid', () => { | ||
|
||
// Arrange | ||
TestUtils.setBodyHtml(`<form><input required value="x"></form>`); | ||
const form = document.querySelector('form'); | ||
const input = form.querySelector('input'); | ||
|
||
const isValidSpy = jest.fn(); | ||
const markFieldAsBlurredSpy = jest.fn(); | ||
|
||
const validation = new FormValidation(form, { | ||
hybridMode: true | ||
}); | ||
|
||
validation.isValid = isValidSpy; | ||
validation.markFieldAsBlurred = markFieldAsBlurredSpy; | ||
validation.setupHybridValidate(); // need to re-run setup as functions have changed | ||
|
||
// Act | ||
TestUtils.dispatchEvent(input, 'keydown'); | ||
TestUtils.dispatchEvent(input, 'blur'); | ||
|
||
// Assert | ||
expect(isValidSpy.mock.calls.length).toBe(1); | ||
expect(markFieldAsBlurredSpy.mock.calls.length).toBe(1); | ||
}); | ||
|
||
it('should not validate on keydown before initial blur', () => { | ||
|
||
// Arrange | ||
TestUtils.setBodyHtml(`<form> | ||
<input type="email" name="email" /> | ||
</form>`); | ||
const form = document.querySelector('form'); | ||
const input = form.querySelector('input'); | ||
|
||
// eslint-disable-next-line no-new | ||
new FormValidation(form, { | ||
hybridMode: true | ||
}); | ||
|
||
// Act | ||
input.value = 'not-a-valid-email'; | ||
TestUtils.dispatchEvent(input, 'keydown'); | ||
|
||
// Assert | ||
const html = TestUtils.getBodyHtml(); | ||
expect(html).toMatchSnapshot(); | ||
|
||
}); | ||
|
||
it('should validate on keydown after initial blur', () => { | ||
|
||
// Arrange | ||
TestUtils.setBodyHtml(`<form> | ||
<input type="email" name="email" /> | ||
</form>`); | ||
const form = document.querySelector('form'); | ||
const input = form.querySelector('input'); | ||
|
||
// eslint-disable-next-line no-new | ||
new FormValidation(form, { | ||
hybridMode: true | ||
}); | ||
|
||
// Act | ||
input.value = 'not-a-valid-email'; | ||
TestUtils.dispatchEvent(input, 'keydown'); | ||
TestUtils.dispatchEvent(input, 'blur'); | ||
TestUtils.dispatchEvent(input, 'keydown'); | ||
|
||
// Assert | ||
const html = TestUtils.getBodyHtml(); | ||
expect(html).toMatchSnapshot(); | ||
|
||
}); | ||
|
||
it('should validate on form submit', () => { | ||
|
||
// Arrange | ||
TestUtils.setBodyHtml(`<form> | ||
<input type="text" required /> | ||
<input type="email" name="email" /> | ||
</form>`); | ||
const form = document.querySelector('form'); | ||
const inputEmail = form.querySelector('input[type=email]'); | ||
|
||
// eslint-disable-next-line no-new | ||
new FormValidation(form, { | ||
hybridMode: true | ||
}); | ||
|
||
// Act | ||
inputEmail.value = 'not-a-valid-email'; | ||
TestUtils.dispatchEvent(inputEmail, 'blur'); | ||
TestUtils.dispatchEvent(form, 'submit'); | ||
|
||
// Assert | ||
const html = TestUtils.getBodyHtml(); | ||
expect(html).toMatchSnapshot(); | ||
}); | ||
|
||
}); |